/* PhotoMetadata.c generated by valac 0.56.19, the Vala compiler
 * generated from PhotoMetadata.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
*/
/**/
/* PhotoMetadata*/
/**/
/* PhotoMetadata is a wrapper class around gexiv2.  The reasoning for this is (a) to facilitiate*/
/* interface changes to meet Photos' requirements without needing modifications of the library*/
/* itself, and (b) some requirements for this class (i.e. obtaining raw metadata) is not available*/
/* in gexiv2, and so must be done by hand.*/
/**/
/* Although it's perceived that Exiv2 will remain Photos' metadata library of choice, this*/
/* may change in the future, and so this wrapper helps with that as well.*/
/**/
/* There is no expectation of thread-safety in this class (yet).*/
/**/
/* Tags come from Exiv2's naming scheme:*/
/* http://www.exiv2.org/metadata.html*/
/**/

#include "io.elementary.photos.h"
#include <glib-object.h>
#include <stdlib.h>
#include <string.h>
#include <glib.h>
#include <gobject/gvaluecollector.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <gio/gio.h>
#include <gexiv2/gexiv2.h>
#include <libexif/exif-data.h>
#include <gee.h>
#include <libexif/exif-mem.h>
#include <float.h>
#include <math.h>

#define PHOTO_METADATA_IPHOTO_TITLE_TAG "Iptc.Application2.ObjectName"
#if !defined(VALA_STRICT_C)
#if !defined(__clang__) && defined(__GNUC__) && (__GNUC__ >= 14)
#pragma GCC diagnostic warning "-Wincompatible-pointer-types"
#elif defined(__clang__) && (__clang_major__ >= 16)
#pragma clang diagnostic ignored "-Wincompatible-function-pointer-types"
#pragma clang diagnostic ignored "-Wincompatible-pointer-types"
#endif
#endif

#define _g_free0(var) (var = (g_free (var), NULL))
typedef struct _ParamSpecHierarchicalKeywordField ParamSpecHierarchicalKeywordField;
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
#define _g_bytes_unref0(var) ((var == NULL) ? NULL : (var = (g_bytes_unref (var), NULL)))
#define _g_error_free0(var) ((var == NULL) ? NULL : (var = (g_error_free (var), NULL)))
typedef struct _ParamSpecPhotoPreview ParamSpecPhotoPreview;
#define _exif_data_unref0(var) ((var == NULL) ? NULL : (var = (exif_data_unref (var), NULL)))
typedef void (*PhotoMetadataSetGenericValue) (const gchar* tag, gpointer user_data);
typedef struct _Block3Data Block3Data;
#define _media_metadata_unref0(var) ((var == NULL) ? NULL : (var = (media_metadata_unref (var), NULL)))
typedef struct _Block4Data Block4Data;
typedef struct _Block5Data Block5Data;
typedef struct _Block6Data Block6Data;
#define _metadata_date_time_unref0(var) ((var == NULL) ? NULL : (var = (metadata_date_time_unref (var), NULL)))
typedef struct _Block7Data Block7Data;
#define _exif_mem_unref0(var) ((var == NULL) ? NULL : (var = (exif_mem_unref (var), NULL)))

#define PHOTO_METADATA_TYPE_INTERNAL_PHOTO_PREVIEW (photo_metadata_internal_photo_preview_get_type ())
#define PHOTO_METADATA_INTERNAL_PHOTO_PREVIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), PHOTO_METADATA_TYPE_INTERNAL_PHOTO_PREVIEW, PhotoMetadataInternalPhotoPreview))
#define PHOTO_METADATA_INTERNAL_PHOTO_PREVIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PHOTO_METADATA_TYPE_INTERNAL_PHOTO_PREVIEW, PhotoMetadataInternalPhotoPreviewClass))
#define PHOTO_METADATA_IS_INTERNAL_PHOTO_PREVIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PHOTO_METADATA_TYPE_INTERNAL_PHOTO_PREVIEW))
#define PHOTO_METADATA_IS_INTERNAL_PHOTO_PREVIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PHOTO_METADATA_TYPE_INTERNAL_PHOTO_PREVIEW))
#define PHOTO_METADATA_INTERNAL_PHOTO_PREVIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PHOTO_METADATA_TYPE_INTERNAL_PHOTO_PREVIEW, PhotoMetadataInternalPhotoPreviewClass))

typedef struct _PhotoMetadataInternalPhotoPreview PhotoMetadataInternalPhotoPreview;
typedef struct _PhotoMetadataInternalPhotoPreviewClass PhotoMetadataInternalPhotoPreviewClass;
#define _hierarchical_keyword_field_unref0(var) ((var == NULL) ? NULL : (var = (hierarchical_keyword_field_unref (var), NULL)))
#define _g_regex_unref0(var) ((var == NULL) ? NULL : (var = (g_regex_unref (var), NULL)))
#define _hierarchical_tag_index_unref0(var) ((var == NULL) ? NULL : (var = (hierarchical_tag_index_unref (var), NULL)))
typedef struct _PhotoMetadataInternalPhotoPreviewPrivate PhotoMetadataInternalPhotoPreviewPrivate;
#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 _ParamSpecHierarchicalKeywordField {
	GParamSpec parent_instance;
};

struct _PhotoPreviewPrivate {
	gchar* name;
	Dimensions dimensions;
	guint32 size;
	gchar* mime_type;
	gchar* extension;
};

struct _ParamSpecPhotoPreview {
	GParamSpec parent_instance;
};

struct _PhotoMetadataPrivate {
	GExiv2Metadata* exiv2;
	ExifData* exif;
	gchar* source_name;
};

struct _Block3Data {
	int _ref_count_;
	PhotoMetadata* self;
	gchar* value;
};

struct _Block4Data {
	int _ref_count_;
	PhotoMetadata* self;
	GeeCollection* values;
};

struct _Block5Data {
	int _ref_count_;
	PhotoMetadata* self;
	glong value;
};

struct _Block6Data {
	int _ref_count_;
	PhotoMetadata* self;
	MetadataRational rational;
};

struct _Block7Data {
	int _ref_count_;
	PhotoMetadata* self;
	MetadataDateTime* date_time;
};

struct _PhotoMetadataInternalPhotoPreview {
	PhotoPreview parent_instance;
	PhotoMetadataInternalPhotoPreviewPrivate * priv;
	PhotoMetadata* owner;
	guint number;
};

struct _PhotoMetadataInternalPhotoPreviewClass {
	PhotoPreviewClass parent_class;
};

static gpointer hierarchical_keyword_field_parent_class = NULL;
static gint PhotoPreview_private_offset;
static gpointer photo_preview_parent_class = NULL;
static gint PhotoMetadata_private_offset;
static gpointer photo_metadata_parent_class = NULL;
static gchar** photo_metadata_date_int64ags;
static gint photo_metadata_date_int64ags_length1;
static gchar** photo_metadata_date_int64ags = NULL;
static gint photo_metadata_date_int64ags_length1 = 0;
static gint _photo_metadata_date_int64ags_size_ = 0;
static gchar** photo_metadata_exposure_date_int64ags;
static gint photo_metadata_exposure_date_int64ags_length1;
static gchar** photo_metadata_exposure_date_int64ags = NULL;
static gint photo_metadata_exposure_date_int64ags_length1 = 0;
static gint _photo_metadata_exposure_date_int64ags_size_ = 0;
static gchar** photo_metadata_digitized_date_int64ags;
static gint photo_metadata_digitized_date_int64ags_length1;
static gchar** photo_metadata_digitized_date_int64ags = NULL;
static gint photo_metadata_digitized_date_int64ags_length1 = 0;
static gint _photo_metadata_digitized_date_int64ags_size_ = 0;
static gchar** photo_metadata_width_tags;
static gint photo_metadata_width_tags_length1;
static gchar** photo_metadata_width_tags = NULL;
static gint photo_metadata_width_tags_length1 = 0;
static gint _photo_metadata_width_tags_size_ = 0;
gchar** photo_metadata_height_tags = NULL;
gint photo_metadata_height_tags_length1 = 0;
static gchar** photo_metadata_standard_title_tags;
static gint photo_metadata_standard_title_tags_length1;
static gchar** photo_metadata_standard_title_tags = NULL;
static gint photo_metadata_standard_title_tags_length1 = 0;
static gint _photo_metadata_standard_title_tags_size_ = 0;
static gchar** photo_metadata_keyword_tags;
static gint photo_metadata_keyword_tags_length1;
static gchar** photo_metadata_keyword_tags = NULL;
static gint photo_metadata_keyword_tags_length1 = 0;
static gint _photo_metadata_keyword_tags_size_ = 0;
static HierarchicalKeywordField** photo_metadata_hierarchical_keyword_tags;
static gint photo_metadata_hierarchical_keyword_tags_length1;
static HierarchicalKeywordField** photo_metadata_hierarchical_keyword_tags = NULL;
static gint photo_metadata_hierarchical_keyword_tags_length1 = 0;
static gint _photo_metadata_hierarchical_keyword_tags_size_ = 0;
static gchar** photo_metadata_artist_tags;
static gint photo_metadata_artist_tags_length1;
static gchar** photo_metadata_artist_tags = NULL;
static gint photo_metadata_artist_tags_length1 = 0;
static gint _photo_metadata_artist_tags_size_ = 0;
static gpointer photo_metadata_internal_photo_preview_parent_class = NULL;

static void hierarchical_keyword_field_finalize (HierarchicalKeywordField * obj);
static GType hierarchical_keyword_field_get_type_once (void);
static GBytes* photo_preview_real_flatten (PhotoPreview* self,
                                    GError** error);
static GdkPixbuf* photo_preview_real_get_pixbuf (PhotoPreview* self,
                                          GError** error);
static void photo_preview_finalize (PhotoPreview * obj);
static GType photo_preview_get_type_once (void);
static void photo_metadata_real_read_from_file (MediaMetadata* base,
                                         GFile* file,
                                         GError** error);
static GeeSet* photo_metadata_create_string_set (PhotoMetadata* self,
                                          GCompareDataFunc compare_func,
                                          gpointer compare_func_target,
                                          GDestroyNotify compare_func_target_destroy_notify);
static void photo_metadata_set_all_generic (PhotoMetadata* self,
                                     gchar** tags,
                                     gint tags_length1,
                                     PhotoMetadataSetOption option,
                                     PhotoMetadataSetGenericValue setter,
                                     gpointer setter_target);
static Block3Data* block3_data_ref (Block3Data* _data3_);
static void block3_data_unref (void * _userdata_);
static void __lambda4_ (Block3Data* _data3_,
                 const gchar* tag);
static void ___lambda4__photo_metadata_set_generic_value (const gchar* tag,
                                                   gpointer self);
static void _vala_array_add94 (gchar** * array,
                        gint* length,
                        gint* size,
                        gchar* value);
static void _vala_array_add95 (gchar** * array,
                        gint* length,
                        gint* size,
                        gchar* value);
static Block4Data* block4_data_ref (Block4Data* _data4_);
static void block4_data_unref (void * _userdata_);
static void __lambda5_ (Block4Data* _data4_,
                 const gchar* tag);
static void ___lambda5__photo_metadata_set_generic_value (const gchar* tag,
                                                   gpointer self);
static Block5Data* block5_data_ref (Block5Data* _data5_);
static void block5_data_unref (void * _userdata_);
static void __lambda6_ (Block5Data* _data5_,
                 const gchar* tag);
static void ___lambda6__photo_metadata_set_generic_value (const gchar* tag,
                                                   gpointer self);
static Block6Data* block6_data_ref (Block6Data* _data6_);
static void block6_data_unref (void * _userdata_);
static void __lambda7_ (Block6Data* _data6_,
                 const gchar* tag);
static void ___lambda7__photo_metadata_set_generic_value (const gchar* tag,
                                                   gpointer self);
static Block7Data* block7_data_ref (Block7Data* _data7_);
static void block7_data_unref (void * _userdata_);
static void __lambda8_ (Block7Data* _data7_,
                 const gchar* tag);
static void ___lambda8__photo_metadata_set_generic_value (const gchar* tag,
                                                   gpointer self);
static guint8* _vala_array_dup15 (guint8* self,
                           gssize length);
static PhotoMetadataInternalPhotoPreview* photo_metadata_internal_photo_preview_new (PhotoMetadata* owner,
                                                                              const gchar* name,
                                                                              guint number,
                                                                              GExiv2PreviewProperties* props);
static PhotoMetadataInternalPhotoPreview* photo_metadata_internal_photo_preview_construct (GType object_type,
                                                                                    PhotoMetadata* owner,
                                                                                    const gchar* name,
                                                                                    guint number,
                                                                                    GExiv2PreviewProperties* props);
static GType photo_metadata_internal_photo_preview_get_type (void) G_GNUC_CONST  G_GNUC_UNUSED ;
static MetadataDateTime* photo_metadata_real_get_creation_date_time (MediaMetadata* base);
static gchar* photo_metadata_real_get_title (MediaMetadata* base);
static gchar* photo_metadata_real_get_comment (MediaMetadata* base);
VALA_EXTERN gchar* hierarchical_tag_utilities_make_flat_tag_safe (const gchar* in_tag);
static void photo_metadata_internal_set_hierarchical_keywords (PhotoMetadata* self,
                                                        HierarchicalTagIndex* index);
VALA_EXTERN GeeList* hierarchical_tag_utilities_enumerate_path_components (const gchar* in_path);
VALA_EXTERN gchar* hierarchical_tag_utilities_canonicalize (const gchar* in_tag,
                                                const gchar* foreign_separator);
static GBytes* photo_metadata_internal_photo_preview_real_flatten (PhotoPreview* base,
                                                            GError** error);
static void photo_metadata_internal_photo_preview_finalize (PhotoPreview * obj);
static GType photo_metadata_internal_photo_preview_get_type_once (void);
static void photo_metadata_finalize (MediaMetadata * obj);
static GType photo_metadata_get_type_once (void);
static void _vala_array_destroy (gpointer array,
                          gssize array_length,
                          GDestroyNotify destroy_func);
static void _vala_array_free (gpointer array,
                       gssize array_length,
                       GDestroyNotify destroy_func);
static gssize _vala_array_length (gpointer array);
static inline gpointer _vala_memdup2 (gconstpointer mem,
                        gsize byte_size);

static GType
metadata_domain_get_type_once (void)
{
	static const GEnumValue values[] = {{METADATA_DOMAIN_UNKNOWN, "METADATA_DOMAIN_UNKNOWN", "unknown"}, {METADATA_DOMAIN_EXIF, "METADATA_DOMAIN_EXIF", "exif"}, {METADATA_DOMAIN_XMP, "METADATA_DOMAIN_XMP", "xmp"}, {METADATA_DOMAIN_IPTC, "METADATA_DOMAIN_IPTC", "iptc"}, {0, NULL, NULL}};
	GType metadata_domain_type_id;
	metadata_domain_type_id = g_enum_register_static ("MetadataDomain", values);
	return metadata_domain_type_id;
}

GType
metadata_domain_get_type (void)
{
	static volatile gsize metadata_domain_type_id__once = 0;
	if (g_once_init_enter (&metadata_domain_type_id__once)) {
		GType metadata_domain_type_id;
		metadata_domain_type_id = metadata_domain_get_type_once ();
		g_once_init_leave (&metadata_domain_type_id__once, metadata_domain_type_id);
	}
	return metadata_domain_type_id__once;
}

HierarchicalKeywordField*
hierarchical_keyword_field_construct (GType object_type,
                                      const gchar* field_name,
                                      const gchar* path_separator,
                                      gboolean wants_leading_separator,
                                      gboolean is_writeable)
{
	HierarchicalKeywordField* self = NULL;
	gchar* _tmp0_;
	gchar* _tmp1_;
	g_return_val_if_fail (field_name != NULL, NULL);
	g_return_val_if_fail (path_separator != NULL, NULL);
	self = (HierarchicalKeywordField*) g_type_create_instance (object_type);
	_tmp0_ = g_strdup (field_name);
	_g_free0 (self->field_name);
	self->field_name = _tmp0_;
	_tmp1_ = g_strdup (path_separator);
	_g_free0 (self->path_separator);
	self->path_separator = _tmp1_;
	self->wants_leading_separator = wants_leading_separator;
	self->is_writeable = is_writeable;
	return self;
}

HierarchicalKeywordField*
hierarchical_keyword_field_new (const gchar* field_name,
                                const gchar* path_separator,
                                gboolean wants_leading_separator,
                                gboolean is_writeable)
{
	return hierarchical_keyword_field_construct (TYPE_HIERARCHICAL_KEYWORD_FIELD, field_name, path_separator, wants_leading_separator, is_writeable);
}

static void
value_hierarchical_keyword_field_init (GValue* value)
{
	value->data[0].v_pointer = NULL;
}

static void
value_hierarchical_keyword_field_free_value (GValue* value)
{
	if (value->data[0].v_pointer) {
		hierarchical_keyword_field_unref (value->data[0].v_pointer);
	}
}

static void
value_hierarchical_keyword_field_copy_value (const GValue* src_value,
                                             GValue* dest_value)
{
	if (src_value->data[0].v_pointer) {
		dest_value->data[0].v_pointer = hierarchical_keyword_field_ref (src_value->data[0].v_pointer);
	} else {
		dest_value->data[0].v_pointer = NULL;
	}
}

static gpointer
value_hierarchical_keyword_field_peek_pointer (const GValue* value)
{
	return value->data[0].v_pointer;
}

static gchar*
value_hierarchical_keyword_field_collect_value (GValue* value,
                                                guint n_collect_values,
                                                GTypeCValue* collect_values,
                                                guint collect_flags)
{
	if (collect_values[0].v_pointer) {
		HierarchicalKeywordField * object;
		object = collect_values[0].v_pointer;
		if (object->parent_instance.g_class == NULL) {
			return g_strconcat ("invalid unclassed object pointer for value type `", G_VALUE_TYPE_NAME (value), "'", NULL);
		} else if (!g_value_type_compatible (G_TYPE_FROM_INSTANCE (object), G_VALUE_TYPE (value))) {
			return g_strconcat ("invalid object type `", g_type_name (G_TYPE_FROM_INSTANCE (object)), "' for value type `", G_VALUE_TYPE_NAME (value), "'", NULL);
		}
		value->data[0].v_pointer = hierarchical_keyword_field_ref (object);
	} else {
		value->data[0].v_pointer = NULL;
	}
	return NULL;
}

static gchar*
value_hierarchical_keyword_field_lcopy_value (const GValue* value,
                                              guint n_collect_values,
                                              GTypeCValue* collect_values,
                                              guint collect_flags)
{
	HierarchicalKeywordField ** object_p;
	object_p = collect_values[0].v_pointer;
	if (!object_p) {
		return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
	}
	if (!value->data[0].v_pointer) {
		*object_p = NULL;
	} else if (collect_flags & G_VALUE_NOCOPY_CONTENTS) {
		*object_p = value->data[0].v_pointer;
	} else {
		*object_p = hierarchical_keyword_field_ref (value->data[0].v_pointer);
	}
	return NULL;
}

GParamSpec*
param_spec_hierarchical_keyword_field (const gchar* name,
                                       const gchar* nick,
                                       const gchar* blurb,
                                       GType object_type,
                                       GParamFlags flags)
{
	ParamSpecHierarchicalKeywordField* spec;
	g_return_val_if_fail (g_type_is_a (object_type, TYPE_HIERARCHICAL_KEYWORD_FIELD), NULL);
	spec = g_param_spec_internal (G_TYPE_PARAM_OBJECT, name, nick, blurb, flags);
	G_PARAM_SPEC (spec)->value_type = object_type;
	return G_PARAM_SPEC (spec);
}

gpointer
value_get_hierarchical_keyword_field (const GValue* value)
{
	g_return_val_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, TYPE_HIERARCHICAL_KEYWORD_FIELD), NULL);
	return value->data[0].v_pointer;
}

void
value_set_hierarchical_keyword_field (GValue* value,
                                      gpointer v_object)
{
	HierarchicalKeywordField * old;
	g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, TYPE_HIERARCHICAL_KEYWORD_FIELD));
	old = value->data[0].v_pointer;
	if (v_object) {
		g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, TYPE_HIERARCHICAL_KEYWORD_FIELD));
		g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (v_object), G_VALUE_TYPE (value)));
		value->data[0].v_pointer = v_object;
		hierarchical_keyword_field_ref (value->data[0].v_pointer);
	} else {
		value->data[0].v_pointer = NULL;
	}
	if (old) {
		hierarchical_keyword_field_unref (old);
	}
}

void
value_take_hierarchical_keyword_field (GValue* value,
                                       gpointer v_object)
{
	HierarchicalKeywordField * old;
	g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, TYPE_HIERARCHICAL_KEYWORD_FIELD));
	old = value->data[0].v_pointer;
	if (v_object) {
		g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, TYPE_HIERARCHICAL_KEYWORD_FIELD));
		g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (v_object), G_VALUE_TYPE (value)));
		value->data[0].v_pointer = v_object;
	} else {
		value->data[0].v_pointer = NULL;
	}
	if (old) {
		hierarchical_keyword_field_unref (old);
	}
}

static void
hierarchical_keyword_field_class_init (HierarchicalKeywordFieldClass * klass,
                                       gpointer klass_data)
{
	hierarchical_keyword_field_parent_class = g_type_class_peek_parent (klass);
	((HierarchicalKeywordFieldClass *) klass)->finalize = hierarchical_keyword_field_finalize;
}

static void
hierarchical_keyword_field_instance_init (HierarchicalKeywordField * self,
                                          gpointer klass)
{
	self->ref_count = 1;
}

static void
hierarchical_keyword_field_finalize (HierarchicalKeywordField * obj)
{
	HierarchicalKeywordField * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, TYPE_HIERARCHICAL_KEYWORD_FIELD, HierarchicalKeywordField);
	g_signal_handlers_destroy (self);
	_g_free0 (self->field_name);
	_g_free0 (self->path_separator);
}

static GType
hierarchical_keyword_field_get_type_once (void)
{
	static const GTypeValueTable g_define_type_value_table = { value_hierarchical_keyword_field_init, value_hierarchical_keyword_field_free_value, value_hierarchical_keyword_field_copy_value, value_hierarchical_keyword_field_peek_pointer, "p", value_hierarchical_keyword_field_collect_value, "p", value_hierarchical_keyword_field_lcopy_value };
	static const GTypeInfo g_define_type_info = { sizeof (HierarchicalKeywordFieldClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) hierarchical_keyword_field_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (HierarchicalKeywordField), 0, (GInstanceInitFunc) hierarchical_keyword_field_instance_init, &g_define_type_value_table };
	static const GTypeFundamentalInfo g_define_type_fundamental_info = { (G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_INSTANTIATABLE | G_TYPE_FLAG_DERIVABLE | G_TYPE_FLAG_DEEP_DERIVABLE) };
	GType hierarchical_keyword_field_type_id;
	hierarchical_keyword_field_type_id = g_type_register_fundamental (g_type_fundamental_next (), "HierarchicalKeywordField", &g_define_type_info, &g_define_type_fundamental_info, 0);
	return hierarchical_keyword_field_type_id;
}

GType
hierarchical_keyword_field_get_type (void)
{
	static volatile gsize hierarchical_keyword_field_type_id__once = 0;
	if (g_once_init_enter (&hierarchical_keyword_field_type_id__once)) {
		GType hierarchical_keyword_field_type_id;
		hierarchical_keyword_field_type_id = hierarchical_keyword_field_get_type_once ();
		g_once_init_leave (&hierarchical_keyword_field_type_id__once, hierarchical_keyword_field_type_id);
	}
	return hierarchical_keyword_field_type_id__once;
}

gpointer
hierarchical_keyword_field_ref (gpointer instance)
{
	HierarchicalKeywordField * self;
	self = instance;
	g_atomic_int_inc (&self->ref_count);
	return instance;
}

void
hierarchical_keyword_field_unref (gpointer instance)
{
	HierarchicalKeywordField * self;
	self = instance;
	if (g_atomic_int_dec_and_test (&self->ref_count)) {
		HIERARCHICAL_KEYWORD_FIELD_GET_CLASS (self)->finalize (self);
		g_type_free_instance ((GTypeInstance *) self);
	}
}

static inline gpointer
photo_preview_get_instance_private (PhotoPreview* self)
{
	return G_STRUCT_MEMBER_P (self, PhotoPreview_private_offset);
}

PhotoPreview*
photo_preview_construct (GType object_type,
                         const gchar* name,
                         Dimensions* dimensions,
                         guint32 size,
                         const gchar* mime_type,
                         const gchar* extension)
{
	PhotoPreview* self = NULL;
	gchar* _tmp0_;
	Dimensions _tmp1_;
	gchar* _tmp2_;
	gchar* _tmp3_;
	g_return_val_if_fail (name != NULL, NULL);
	g_return_val_if_fail (dimensions != NULL, NULL);
	g_return_val_if_fail (mime_type != NULL, NULL);
	g_return_val_if_fail (extension != NULL, NULL);
	self = (PhotoPreview*) g_type_create_instance (object_type);
	_tmp0_ = g_strdup (name);
	_g_free0 (self->priv->name);
	self->priv->name = _tmp0_;
	_tmp1_ = *dimensions;
	self->priv->dimensions = _tmp1_;
	self->priv->size = size;
	_tmp2_ = g_strdup (mime_type);
	_g_free0 (self->priv->mime_type);
	self->priv->mime_type = _tmp2_;
	_tmp3_ = g_strdup (extension);
	_g_free0 (self->priv->extension);
	self->priv->extension = _tmp3_;
	return self;
}

gchar*
photo_preview_get_name (PhotoPreview* self)
{
	const gchar* _tmp0_;
	gchar* _tmp1_;
	gchar* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->name;
	_tmp1_ = g_strdup (_tmp0_);
	result = _tmp1_;
	return result;
}

void
photo_preview_get_pixel_dimensions (PhotoPreview* self,
                                    Dimensions* result)
{
	Dimensions _tmp0_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->dimensions;
	*result = _tmp0_;
	return;
}

guint32
photo_preview_get_size (PhotoPreview* self)
{
	guint32 result;
	g_return_val_if_fail (self != NULL, 0U);
	result = self->priv->size;
	return result;
}

gchar*
photo_preview_get_mime_type (PhotoPreview* self)
{
	const gchar* _tmp0_;
	gchar* _tmp1_;
	gchar* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->mime_type;
	_tmp1_ = g_strdup (_tmp0_);
	result = _tmp1_;
	return result;
}

gchar*
photo_preview_get_extension (PhotoPreview* self)
{
	const gchar* _tmp0_;
	gchar* _tmp1_;
	gchar* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->extension;
	_tmp1_ = g_strdup (_tmp0_);
	result = _tmp1_;
	return result;
}

static GBytes*
photo_preview_real_flatten (PhotoPreview* self,
                            GError** error)
{
	g_critical ("Type `%s' does not implement abstract method `photo_preview_flatten'", g_type_name (G_TYPE_FROM_INSTANCE (self)));
	return NULL;
}

GBytes*
photo_preview_flatten (PhotoPreview* self,
                       GError** error)
{
	PhotoPreviewClass* _klass_;
	g_return_val_if_fail (self != NULL, NULL);
	_klass_ = PHOTO_PREVIEW_GET_CLASS (self);
	if (_klass_->flatten) {
		return _klass_->flatten (self, error);
	}
	return NULL;
}

static GdkPixbuf*
photo_preview_real_get_pixbuf (PhotoPreview* self,
                               GError** error)
{
	GBytes* flattened = NULL;
	GBytes* _tmp0_;
	GError* _inner_error0_ = NULL;
	GdkPixbuf* result;
	_tmp0_ = photo_preview_flatten (self, &_inner_error0_);
	flattened = _tmp0_;
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		g_propagate_error (error, _inner_error0_);
		return NULL;
	}
	{
		GdkPixbuf* _tmp1_ = NULL;
		GMemoryInputStream* _tmp2_;
		GMemoryInputStream* _tmp3_;
		GdkPixbuf* _tmp4_;
		GdkPixbuf* _tmp5_;
		GdkPixbuf* _tmp6_;
		_tmp2_ = (GMemoryInputStream*) g_memory_input_stream_new_from_bytes (flattened);
		_tmp3_ = _tmp2_;
		_tmp4_ = gdk_pixbuf_new_from_stream ((GInputStream*) _tmp3_, NULL, &_inner_error0_);
		_tmp5_ = _tmp4_;
		_g_object_unref0 (_tmp3_);
		_tmp1_ = _tmp5_;
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			goto __catch0_g_error;
		}
		_tmp6_ = _tmp1_;
		_tmp1_ = NULL;
		result = _tmp6_;
		_g_object_unref0 (_tmp1_);
		_g_bytes_unref0 (flattened);
		return result;
	}
	goto __finally0;
	__catch0_g_error:
	{
		GError* err = NULL;
		const gchar* _tmp7_;
		GError* _tmp8_;
		const gchar* _tmp9_;
		err = _inner_error0_;
		_inner_error0_ = NULL;
		_tmp7_ = self->priv->name;
		_tmp8_ = err;
		_tmp9_ = _tmp8_->message;
		g_warning ("PhotoMetadata.vala:104: Unable to decode thumbnail for %s: %s", _tmp7_, _tmp9_);
		result = NULL;
		_g_error_free0 (err);
		_g_bytes_unref0 (flattened);
		return result;
	}
	__finally0:
	g_propagate_error (error, _inner_error0_);
	_g_bytes_unref0 (flattened);
	return NULL;
}

GdkPixbuf*
photo_preview_get_pixbuf (PhotoPreview* self,
                          GError** error)
{
	PhotoPreviewClass* _klass_;
	g_return_val_if_fail (self != NULL, NULL);
	_klass_ = PHOTO_PREVIEW_GET_CLASS (self);
	if (_klass_->get_pixbuf) {
		return _klass_->get_pixbuf (self, error);
	}
	return NULL;
}

static void
value_photo_preview_init (GValue* value)
{
	value->data[0].v_pointer = NULL;
}

static void
value_photo_preview_free_value (GValue* value)
{
	if (value->data[0].v_pointer) {
		photo_preview_unref (value->data[0].v_pointer);
	}
}

static void
value_photo_preview_copy_value (const GValue* src_value,
                                GValue* dest_value)
{
	if (src_value->data[0].v_pointer) {
		dest_value->data[0].v_pointer = photo_preview_ref (src_value->data[0].v_pointer);
	} else {
		dest_value->data[0].v_pointer = NULL;
	}
}

static gpointer
value_photo_preview_peek_pointer (const GValue* value)
{
	return value->data[0].v_pointer;
}

static gchar*
value_photo_preview_collect_value (GValue* value,
                                   guint n_collect_values,
                                   GTypeCValue* collect_values,
                                   guint collect_flags)
{
	if (collect_values[0].v_pointer) {
		PhotoPreview * object;
		object = collect_values[0].v_pointer;
		if (object->parent_instance.g_class == NULL) {
			return g_strconcat ("invalid unclassed object pointer for value type `", G_VALUE_TYPE_NAME (value), "'", NULL);
		} else if (!g_value_type_compatible (G_TYPE_FROM_INSTANCE (object), G_VALUE_TYPE (value))) {
			return g_strconcat ("invalid object type `", g_type_name (G_TYPE_FROM_INSTANCE (object)), "' for value type `", G_VALUE_TYPE_NAME (value), "'", NULL);
		}
		value->data[0].v_pointer = photo_preview_ref (object);
	} else {
		value->data[0].v_pointer = NULL;
	}
	return NULL;
}

static gchar*
value_photo_preview_lcopy_value (const GValue* value,
                                 guint n_collect_values,
                                 GTypeCValue* collect_values,
                                 guint collect_flags)
{
	PhotoPreview ** object_p;
	object_p = collect_values[0].v_pointer;
	if (!object_p) {
		return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
	}
	if (!value->data[0].v_pointer) {
		*object_p = NULL;
	} else if (collect_flags & G_VALUE_NOCOPY_CONTENTS) {
		*object_p = value->data[0].v_pointer;
	} else {
		*object_p = photo_preview_ref (value->data[0].v_pointer);
	}
	return NULL;
}

GParamSpec*
param_spec_photo_preview (const gchar* name,
                          const gchar* nick,
                          const gchar* blurb,
                          GType object_type,
                          GParamFlags flags)
{
	ParamSpecPhotoPreview* spec;
	g_return_val_if_fail (g_type_is_a (object_type, TYPE_PHOTO_PREVIEW), NULL);
	spec = g_param_spec_internal (G_TYPE_PARAM_OBJECT, name, nick, blurb, flags);
	G_PARAM_SPEC (spec)->value_type = object_type;
	return G_PARAM_SPEC (spec);
}

gpointer
value_get_photo_preview (const GValue* value)
{
	g_return_val_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, TYPE_PHOTO_PREVIEW), NULL);
	return value->data[0].v_pointer;
}

void
value_set_photo_preview (GValue* value,
                         gpointer v_object)
{
	PhotoPreview * old;
	g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, TYPE_PHOTO_PREVIEW));
	old = value->data[0].v_pointer;
	if (v_object) {
		g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, TYPE_PHOTO_PREVIEW));
		g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (v_object), G_VALUE_TYPE (value)));
		value->data[0].v_pointer = v_object;
		photo_preview_ref (value->data[0].v_pointer);
	} else {
		value->data[0].v_pointer = NULL;
	}
	if (old) {
		photo_preview_unref (old);
	}
}

void
value_take_photo_preview (GValue* value,
                          gpointer v_object)
{
	PhotoPreview * old;
	g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, TYPE_PHOTO_PREVIEW));
	old = value->data[0].v_pointer;
	if (v_object) {
		g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, TYPE_PHOTO_PREVIEW));
		g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (v_object), G_VALUE_TYPE (value)));
		value->data[0].v_pointer = v_object;
	} else {
		value->data[0].v_pointer = NULL;
	}
	if (old) {
		photo_preview_unref (old);
	}
}

static void
photo_preview_class_init (PhotoPreviewClass * klass,
                          gpointer klass_data)
{
	photo_preview_parent_class = g_type_class_peek_parent (klass);
	((PhotoPreviewClass *) klass)->finalize = photo_preview_finalize;
	g_type_class_adjust_private_offset (klass, &PhotoPreview_private_offset);
	((PhotoPreviewClass *) klass)->flatten = (GBytes* (*) (PhotoPreview*, GError**)) photo_preview_real_flatten;
	((PhotoPreviewClass *) klass)->get_pixbuf = (GdkPixbuf* (*) (PhotoPreview*, GError**)) photo_preview_real_get_pixbuf;
}

static void
photo_preview_instance_init (PhotoPreview * self,
                             gpointer klass)
{
	self->priv = photo_preview_get_instance_private (self);
	self->ref_count = 1;
}

static void
photo_preview_finalize (PhotoPreview * obj)
{
	PhotoPreview * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, TYPE_PHOTO_PREVIEW, PhotoPreview);
	g_signal_handlers_destroy (self);
	_g_free0 (self->priv->name);
	_g_free0 (self->priv->mime_type);
	_g_free0 (self->priv->extension);
}

static GType
photo_preview_get_type_once (void)
{
	static const GTypeValueTable g_define_type_value_table = { value_photo_preview_init, value_photo_preview_free_value, value_photo_preview_copy_value, value_photo_preview_peek_pointer, "p", value_photo_preview_collect_value, "p", value_photo_preview_lcopy_value };
	static const GTypeInfo g_define_type_info = { sizeof (PhotoPreviewClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) photo_preview_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (PhotoPreview), 0, (GInstanceInitFunc) photo_preview_instance_init, &g_define_type_value_table };
	static const GTypeFundamentalInfo g_define_type_fundamental_info = { (G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_INSTANTIATABLE | G_TYPE_FLAG_DERIVABLE | G_TYPE_FLAG_DEEP_DERIVABLE) };
	GType photo_preview_type_id;
	photo_preview_type_id = g_type_register_fundamental (g_type_fundamental_next (), "PhotoPreview", &g_define_type_info, &g_define_type_fundamental_info, G_TYPE_FLAG_ABSTRACT);
	PhotoPreview_private_offset = g_type_add_instance_private (photo_preview_type_id, sizeof (PhotoPreviewPrivate));
	return photo_preview_type_id;
}

GType
photo_preview_get_type (void)
{
	static volatile gsize photo_preview_type_id__once = 0;
	if (g_once_init_enter (&photo_preview_type_id__once)) {
		GType photo_preview_type_id;
		photo_preview_type_id = photo_preview_get_type_once ();
		g_once_init_leave (&photo_preview_type_id__once, photo_preview_type_id);
	}
	return photo_preview_type_id__once;
}

gpointer
photo_preview_ref (gpointer instance)
{
	PhotoPreview * self;
	self = instance;
	g_atomic_int_inc (&self->ref_count);
	return instance;
}

void
photo_preview_unref (gpointer instance)
{
	PhotoPreview * self;
	self = instance;
	if (g_atomic_int_dec_and_test (&self->ref_count)) {
		PHOTO_PREVIEW_GET_CLASS (self)->finalize (self);
		g_type_free_instance ((GTypeInstance *) self);
	}
}

static inline gpointer
photo_metadata_get_instance_private (PhotoMetadata* self)
{
	return G_STRUCT_MEMBER_P (self, PhotoMetadata_private_offset);
}

static GType
photo_metadata_set_option_get_type_once (void)
{
	static const GEnumValue values[] = {{PHOTO_METADATA_SET_OPTION_ALL_DOMAINS, "PHOTO_METADATA_SET_OPTION_ALL_DOMAINS", "all-domains"}, {PHOTO_METADATA_SET_OPTION_ONLY_IF_DOMAIN_PRESENT, "PHOTO_METADATA_SET_OPTION_ONLY_IF_DOMAIN_PRESENT", "only-if-domain-present"}, {PHOTO_METADATA_SET_OPTION_AT_LEAST_DEFAULT_DOMAIN, "PHOTO_METADATA_SET_OPTION_AT_LEAST_DEFAULT_DOMAIN", "at-least-default-domain"}, {0, NULL, NULL}};
	GType photo_metadata_set_option_type_id;
	photo_metadata_set_option_type_id = g_enum_register_static ("PhotoMetadataSetOption", values);
	return photo_metadata_set_option_type_id;
}

GType
photo_metadata_set_option_get_type (void)
{
	static volatile gsize photo_metadata_set_option_type_id__once = 0;
	if (g_once_init_enter (&photo_metadata_set_option_type_id__once)) {
		GType photo_metadata_set_option_type_id;
		photo_metadata_set_option_type_id = photo_metadata_set_option_get_type_once ();
		g_once_init_leave (&photo_metadata_set_option_type_id__once, photo_metadata_set_option_type_id);
	}
	return photo_metadata_set_option_type_id__once;
}

PhotoMetadata*
photo_metadata_construct (GType object_type)
{
	PhotoMetadata* self = NULL;
	self = (PhotoMetadata*) media_metadata_construct (object_type);
	return self;
}

PhotoMetadata*
photo_metadata_new (void)
{
	return photo_metadata_construct (TYPE_PHOTO_METADATA);
}

static void
photo_metadata_real_read_from_file (MediaMetadata* base,
                                    GFile* file,
                                    GError** error)
{
	PhotoMetadata * self;
	GExiv2Metadata* _tmp0_;
	GExiv2Metadata* _tmp1_;
	gchar* _tmp2_;
	gchar* _tmp3_;
	gchar* _tmp4_;
	gchar* _tmp5_;
	ExifData* _tmp6_;
	gchar* _tmp7_;
	GError* _inner_error0_ = NULL;
	self = (PhotoMetadata*) base;
	g_return_if_fail (file != NULL);
	_tmp0_ = gexiv2_metadata_new ();
	_g_object_unref0 (self->priv->exiv2);
	self->priv->exiv2 = _tmp0_;
	_exif_data_unref0 (self->priv->exif);
	self->priv->exif = NULL;
	_tmp1_ = self->priv->exiv2;
	_tmp2_ = g_file_get_path (file);
	_tmp3_ = _tmp2_;
	gexiv2_metadata_open_path (_tmp1_, _tmp3_, &_inner_error0_);
	_g_free0 (_tmp3_);
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		g_propagate_error (error, _inner_error0_);
		return;
	}
	_tmp4_ = g_file_get_path (file);
	_tmp5_ = _tmp4_;
	_tmp6_ = exif_data_new_from_file (_tmp5_);
	_exif_data_unref0 (self->priv->exif);
	self->priv->exif = _tmp6_;
	_g_free0 (_tmp5_);
	_tmp7_ = g_file_get_basename (file);
	_g_free0 (self->priv->source_name);
	self->priv->source_name = _tmp7_;
}

void
photo_metadata_write_to_file (PhotoMetadata* self,
                              GFile* file,
                              GError** error)
{
	GExiv2Metadata* _tmp0_;
	gchar* _tmp1_;
	gchar* _tmp2_;
	GError* _inner_error0_ = NULL;
	g_return_if_fail (self != NULL);
	g_return_if_fail (file != NULL);
	_tmp0_ = self->priv->exiv2;
	_tmp1_ = g_file_get_path (file);
	_tmp2_ = _tmp1_;
	gexiv2_metadata_save_file (_tmp0_, _tmp2_, &_inner_error0_);
	_g_free0 (_tmp2_);
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		g_propagate_error (error, _inner_error0_);
		return;
	}
}

void
photo_metadata_read_from_buffer (PhotoMetadata* self,
                                 guint8* buffer,
                                 gint buffer_length1,
                                 gint length,
                                 GError** error)
{
	GExiv2Metadata* _tmp0_;
	GExiv2Metadata* _tmp1_;
	ExifData* _tmp2_;
	gchar* _tmp3_;
	GError* _inner_error0_ = NULL;
	g_return_if_fail (self != NULL);
	if (length <= 0) {
		length = buffer_length1;
	}
	_vala_assert (buffer_length1 >= length, "buffer.length >= length");
	_tmp0_ = gexiv2_metadata_new ();
	_g_object_unref0 (self->priv->exiv2);
	self->priv->exiv2 = _tmp0_;
	_exif_data_unref0 (self->priv->exif);
	self->priv->exif = NULL;
	_tmp1_ = self->priv->exiv2;
	gexiv2_metadata_open_buf (_tmp1_, buffer + 0, (glong) (length - 0), &_inner_error0_);
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		g_propagate_error (error, _inner_error0_);
		return;
	}
	_tmp2_ = exif_data_new_from_data (buffer + 0, (gint) (length - 0));
	_exif_data_unref0 (self->priv->exif);
	self->priv->exif = _tmp2_;
	_tmp3_ = g_strdup_printf ("<memory buffer %d bytes>", length);
	_g_free0 (self->priv->source_name);
	self->priv->source_name = _tmp3_;
}

void
photo_metadata_read_from_app1_segment (PhotoMetadata* self,
                                       GBytes* buffer,
                                       GError** error)
{
	GExiv2Metadata* _tmp0_;
	GExiv2Metadata* _tmp1_;
	gsize _tmp2_ = 0;
	guint8* _tmp3_;
	gsize _tmp4_ = 0;
	guint8* _tmp5_;
	ExifData* _tmp6_;
	gchar* _tmp7_;
	GError* _inner_error0_ = NULL;
	g_return_if_fail (self != NULL);
	g_return_if_fail (buffer != NULL);
	_tmp0_ = gexiv2_metadata_new ();
	_g_object_unref0 (self->priv->exiv2);
	self->priv->exiv2 = _tmp0_;
	_exif_data_unref0 (self->priv->exif);
	self->priv->exif = NULL;
	_tmp1_ = self->priv->exiv2;
	_tmp3_ = g_bytes_get_data (buffer, &_tmp2_);
	gexiv2_metadata_from_app1_segment (_tmp1_, _tmp3_, (glong) _tmp2_, &_inner_error0_);
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		g_propagate_error (error, _inner_error0_);
		return;
	}
	_tmp5_ = g_bytes_get_data (buffer, &_tmp4_);
	_tmp6_ = exif_data_new_from_data (_tmp5_, (gint) _tmp4_);
	_exif_data_unref0 (self->priv->exif);
	self->priv->exif = _tmp6_;
	_tmp7_ = g_strdup_printf ("<app1 segment %zu bytes>", g_bytes_get_size (buffer));
	_g_free0 (self->priv->source_name);
	self->priv->source_name = _tmp7_;
}

MetadataDomain
photo_metadata_get_tag_domain (const gchar* tag)
{
	MetadataDomain result;
	g_return_val_if_fail (tag != NULL, 0);
	if (gexiv2_metadata_is_exif_tag (tag)) {
		result = METADATA_DOMAIN_EXIF;
		return result;
	}
	if (gexiv2_metadata_is_xmp_tag (tag)) {
		result = METADATA_DOMAIN_XMP;
		return result;
	}
	if (gexiv2_metadata_is_iptc_tag (tag)) {
		result = METADATA_DOMAIN_IPTC;
		return result;
	}
	result = METADATA_DOMAIN_UNKNOWN;
	return result;
}

gboolean
photo_metadata_has_domain (PhotoMetadata* self,
                           MetadataDomain domain)
{
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	switch (domain) {
		case METADATA_DOMAIN_EXIF:
		{
			GExiv2Metadata* _tmp0_;
			_tmp0_ = self->priv->exiv2;
			result = gexiv2_metadata_has_exif (_tmp0_);
			return result;
		}
		case METADATA_DOMAIN_XMP:
		{
			GExiv2Metadata* _tmp1_;
			_tmp1_ = self->priv->exiv2;
			result = gexiv2_metadata_has_xmp (_tmp1_);
			return result;
		}
		case METADATA_DOMAIN_IPTC:
		{
			GExiv2Metadata* _tmp2_;
			_tmp2_ = self->priv->exiv2;
			result = gexiv2_metadata_has_iptc (_tmp2_);
			return result;
		}
		default:
		case METADATA_DOMAIN_UNKNOWN:
		{
			result = FALSE;
			return result;
		}
	}
}

gboolean
photo_metadata_has_exif (PhotoMetadata* self)
{
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	result = photo_metadata_has_domain (self, METADATA_DOMAIN_EXIF);
	return result;
}

gboolean
photo_metadata_has_xmp (PhotoMetadata* self)
{
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	result = photo_metadata_has_domain (self, METADATA_DOMAIN_XMP);
	return result;
}

gboolean
photo_metadata_has_iptc (PhotoMetadata* self)
{
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	result = photo_metadata_has_domain (self, METADATA_DOMAIN_IPTC);
	return result;
}

gboolean
photo_metadata_can_write_to_domain (PhotoMetadata* self,
                                    MetadataDomain domain)
{
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	switch (domain) {
		case METADATA_DOMAIN_EXIF:
		{
			GExiv2Metadata* _tmp0_;
			_tmp0_ = self->priv->exiv2;
			result = gexiv2_metadata_get_supports_exif (_tmp0_);
			return result;
		}
		case METADATA_DOMAIN_XMP:
		{
			GExiv2Metadata* _tmp1_;
			_tmp1_ = self->priv->exiv2;
			result = gexiv2_metadata_get_supports_xmp (_tmp1_);
			return result;
		}
		case METADATA_DOMAIN_IPTC:
		{
			GExiv2Metadata* _tmp2_;
			_tmp2_ = self->priv->exiv2;
			result = gexiv2_metadata_get_supports_iptc (_tmp2_);
			return result;
		}
		default:
		case METADATA_DOMAIN_UNKNOWN:
		{
			result = FALSE;
			return result;
		}
	}
}

gboolean
photo_metadata_can_write_exif (PhotoMetadata* self)
{
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	result = photo_metadata_can_write_to_domain (self, METADATA_DOMAIN_EXIF);
	return result;
}

gboolean
photo_metadata_can_write_xmp (PhotoMetadata* self)
{
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	result = photo_metadata_can_write_to_domain (self, METADATA_DOMAIN_XMP);
	return result;
}

gboolean
photo_metadata_can_write_iptc (PhotoMetadata* self)
{
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	result = photo_metadata_can_write_to_domain (self, METADATA_DOMAIN_IPTC);
	return result;
}

gboolean
photo_metadata_has_tag (PhotoMetadata* self,
                        const gchar* tag)
{
	GExiv2Metadata* _tmp0_;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	g_return_val_if_fail (tag != NULL, FALSE);
	_tmp0_ = self->priv->exiv2;
	result = gexiv2_metadata_has_tag (_tmp0_, tag);
	return result;
}

static GeeSet*
photo_metadata_create_string_set (PhotoMetadata* self,
                                  GCompareDataFunc compare_func,
                                  gpointer compare_func_target,
                                  GDestroyNotify compare_func_target_destroy_notify)
{
	GeeSet* result;
	g_return_val_if_fail (self != NULL, NULL);
	if (compare_func == NULL) {
		GeeHashSet* _tmp0_;
		_tmp0_ = gee_hash_set_new (G_TYPE_STRING, (GBoxedCopyFunc) g_strdup, (GDestroyNotify) g_free, NULL, NULL, NULL, NULL, NULL, NULL);
		result = (GeeSet*) _tmp0_;
		(compare_func_target_destroy_notify == NULL) ? NULL : (compare_func_target_destroy_notify (compare_func_target), NULL);
		compare_func = NULL;
		compare_func_target = NULL;
		compare_func_target_destroy_notify = NULL;
		return result;
	} else {
		GCompareDataFunc _tmp1_;
		gpointer _tmp1__target;
		GDestroyNotify _tmp1__target_destroy_notify;
		GeeTreeSet* _tmp2_;
		_tmp1_ = compare_func;
		_tmp1__target = compare_func_target;
		_tmp1__target_destroy_notify = compare_func_target_destroy_notify;
		compare_func = NULL;
		compare_func_target = NULL;
		compare_func_target_destroy_notify = NULL;
		_tmp2_ = gee_tree_set_new (G_TYPE_STRING, (GBoxedCopyFunc) g_strdup, (GDestroyNotify) g_free, _tmp1_, _tmp1__target, _tmp1__target_destroy_notify);
		result = (GeeSet*) _tmp2_;
		(compare_func_target_destroy_notify == NULL) ? NULL : (compare_func_target_destroy_notify (compare_func_target), NULL);
		compare_func = NULL;
		compare_func_target = NULL;
		compare_func_target_destroy_notify = NULL;
		return result;
	}
}

GeeCollection*
photo_metadata_get_tags (PhotoMetadata* self,
                         MetadataDomain domain,
                         GCompareDataFunc compare_func,
                         gpointer compare_func_target,
                         GDestroyNotify compare_func_target_destroy_notify)
{
	gchar** tags = NULL;
	gint tags_length1;
	gint _tags_size_;
	gboolean _tmp9_ = FALSE;
	gchar** _tmp10_;
	gint _tmp10__length1;
	GeeCollection* collection = NULL;
	GCompareDataFunc _tmp12_;
	gpointer _tmp12__target;
	GDestroyNotify _tmp12__target_destroy_notify;
	GeeSet* _tmp13_;
	gchar** _tmp14_;
	gint _tmp14__length1;
	GeeCollection* result;
	g_return_val_if_fail (self != NULL, NULL);
	tags = NULL;
	tags_length1 = 0;
	_tags_size_ = tags_length1;
	switch (domain) {
		case METADATA_DOMAIN_EXIF:
		{
			GExiv2Metadata* _tmp0_;
			gchar** _tmp1_;
			gchar** _tmp2_;
			_tmp0_ = self->priv->exiv2;
			_tmp2_ = _tmp1_ = gexiv2_metadata_get_exif_tags (_tmp0_);
			tags = (_vala_array_free (tags, tags_length1, (GDestroyNotify) g_free), NULL);
			tags = _tmp2_;
			tags_length1 = _vala_array_length (_tmp1_);
			_tags_size_ = tags_length1;
			break;
		}
		case METADATA_DOMAIN_XMP:
		{
			GExiv2Metadata* _tmp3_;
			gchar** _tmp4_;
			gchar** _tmp5_;
			_tmp3_ = self->priv->exiv2;
			_tmp5_ = _tmp4_ = gexiv2_metadata_get_xmp_tags (_tmp3_);
			tags = (_vala_array_free (tags, tags_length1, (GDestroyNotify) g_free), NULL);
			tags = _tmp5_;
			tags_length1 = _vala_array_length (_tmp4_);
			_tags_size_ = tags_length1;
			break;
		}
		case METADATA_DOMAIN_IPTC:
		{
			GExiv2Metadata* _tmp6_;
			gchar** _tmp7_;
			gchar** _tmp8_;
			_tmp6_ = self->priv->exiv2;
			_tmp8_ = _tmp7_ = gexiv2_metadata_get_iptc_tags (_tmp6_);
			tags = (_vala_array_free (tags, tags_length1, (GDestroyNotify) g_free), NULL);
			tags = _tmp8_;
			tags_length1 = _vala_array_length (_tmp7_);
			_tags_size_ = tags_length1;
			break;
		}
		default:
		break;
	}
	_tmp10_ = tags;
	_tmp10__length1 = tags_length1;
	if (_tmp10_ == NULL) {
		_tmp9_ = TRUE;
	} else {
		gchar** _tmp11_;
		gint _tmp11__length1;
		_tmp11_ = tags;
		_tmp11__length1 = tags_length1;
		_tmp9_ = _tmp11__length1 == 0;
	}
	if (_tmp9_) {
		result = NULL;
		tags = (_vala_array_free (tags, tags_length1, (GDestroyNotify) g_free), NULL);
		(compare_func_target_destroy_notify == NULL) ? NULL : (compare_func_target_destroy_notify (compare_func_target), NULL);
		compare_func = NULL;
		compare_func_target = NULL;
		compare_func_target_destroy_notify = NULL;
		return result;
	}
	_tmp12_ = compare_func;
	_tmp12__target = compare_func_target;
	_tmp12__target_destroy_notify = compare_func_target_destroy_notify;
	compare_func = NULL;
	compare_func_target = NULL;
	compare_func_target_destroy_notify = NULL;
	_tmp13_ = photo_metadata_create_string_set (self, _tmp12_, _tmp12__target, _tmp12__target_destroy_notify);
	collection = (GeeCollection*) _tmp13_;
	_tmp14_ = tags;
	_tmp14__length1 = tags_length1;
	{
		gchar** tag_collection = NULL;
		gint tag_collection_length1 = 0;
		gint _tag_collection_size_ = 0;
		gint tag_it = 0;
		tag_collection = _tmp14_;
		tag_collection_length1 = _tmp14__length1;
		for (tag_it = 0; tag_it < tag_collection_length1; tag_it = tag_it + 1) {
			gchar* _tmp15_;
			gchar* tag = NULL;
			_tmp15_ = g_strdup (tag_collection[tag_it]);
			tag = _tmp15_;
			{
				GeeCollection* _tmp16_;
				const gchar* _tmp17_;
				_tmp16_ = collection;
				_tmp17_ = tag;
				gee_collection_add (_tmp16_, _tmp17_);
				_g_free0 (tag);
			}
		}
	}
	result = collection;
	tags = (_vala_array_free (tags, tags_length1, (GDestroyNotify) g_free), NULL);
	(compare_func_target_destroy_notify == NULL) ? NULL : (compare_func_target_destroy_notify (compare_func_target), NULL);
	compare_func = NULL;
	compare_func_target = NULL;
	compare_func_target_destroy_notify = NULL;
	return result;
}

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

GeeCollection*
photo_metadata_get_all_tags (PhotoMetadata* self,
                             GCompareDataFunc compare_func,
                             gpointer compare_func_target,
                             GDestroyNotify compare_func_target_destroy_notify)
{
	GeeCollection* all_tags = NULL;
	GCompareDataFunc _tmp0_;
	gpointer _tmp0__target;
	GDestroyNotify _tmp0__target_destroy_notify;
	GeeSet* _tmp1_;
	GeeCollection* exif_tags = NULL;
	GeeCollection* _tmp2_;
	gboolean _tmp3_ = FALSE;
	GeeCollection* _tmp4_;
	GeeCollection* xmp_tags = NULL;
	GeeCollection* _tmp10_;
	gboolean _tmp11_ = FALSE;
	GeeCollection* _tmp12_;
	GeeCollection* iptc_tags = NULL;
	GeeCollection* _tmp18_;
	gboolean _tmp19_ = FALSE;
	GeeCollection* _tmp20_;
	GeeCollection* _tmp26_ = NULL;
	GeeCollection* _tmp27_;
	gint _tmp28_;
	gint _tmp29_;
	GeeCollection* _tmp31_;
	GeeCollection* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = compare_func;
	_tmp0__target = compare_func_target;
	_tmp0__target_destroy_notify = compare_func_target_destroy_notify;
	compare_func = NULL;
	compare_func_target = NULL;
	compare_func_target_destroy_notify = NULL;
	_tmp1_ = photo_metadata_create_string_set (self, _tmp0_, _tmp0__target, _tmp0__target_destroy_notify);
	all_tags = (GeeCollection*) _tmp1_;
	_tmp2_ = photo_metadata_get_tags (self, METADATA_DOMAIN_EXIF, NULL, NULL, NULL);
	exif_tags = _tmp2_;
	_tmp4_ = exif_tags;
	if (_tmp4_ != NULL) {
		GeeCollection* _tmp5_;
		gint _tmp6_;
		gint _tmp7_;
		_tmp5_ = exif_tags;
		_tmp6_ = gee_collection_get_size (_tmp5_);
		_tmp7_ = _tmp6_;
		_tmp3_ = _tmp7_ > 0;
	} else {
		_tmp3_ = FALSE;
	}
	if (_tmp3_) {
		GeeCollection* _tmp8_;
		GeeCollection* _tmp9_;
		_tmp8_ = all_tags;
		_tmp9_ = exif_tags;
		gee_collection_add_all (_tmp8_, _tmp9_);
	}
	_tmp10_ = photo_metadata_get_tags (self, METADATA_DOMAIN_XMP, NULL, NULL, NULL);
	xmp_tags = _tmp10_;
	_tmp12_ = xmp_tags;
	if (_tmp12_ != NULL) {
		GeeCollection* _tmp13_;
		gint _tmp14_;
		gint _tmp15_;
		_tmp13_ = xmp_tags;
		_tmp14_ = gee_collection_get_size (_tmp13_);
		_tmp15_ = _tmp14_;
		_tmp11_ = _tmp15_ > 0;
	} else {
		_tmp11_ = FALSE;
	}
	if (_tmp11_) {
		GeeCollection* _tmp16_;
		GeeCollection* _tmp17_;
		_tmp16_ = all_tags;
		_tmp17_ = xmp_tags;
		gee_collection_add_all (_tmp16_, _tmp17_);
	}
	_tmp18_ = photo_metadata_get_tags (self, METADATA_DOMAIN_IPTC, NULL, NULL, NULL);
	iptc_tags = _tmp18_;
	_tmp20_ = iptc_tags;
	if (_tmp20_ != NULL) {
		GeeCollection* _tmp21_;
		gint _tmp22_;
		gint _tmp23_;
		_tmp21_ = iptc_tags;
		_tmp22_ = gee_collection_get_size (_tmp21_);
		_tmp23_ = _tmp22_;
		_tmp19_ = _tmp23_ > 0;
	} else {
		_tmp19_ = FALSE;
	}
	if (_tmp19_) {
		GeeCollection* _tmp24_;
		GeeCollection* _tmp25_;
		_tmp24_ = all_tags;
		_tmp25_ = iptc_tags;
		gee_collection_add_all (_tmp24_, _tmp25_);
	}
	_tmp27_ = all_tags;
	_tmp28_ = gee_collection_get_size (_tmp27_);
	_tmp29_ = _tmp28_;
	if (_tmp29_ > 0) {
		GeeCollection* _tmp30_;
		_tmp30_ = all_tags;
		_tmp26_ = _tmp30_;
	} else {
		_tmp26_ = NULL;
	}
	_tmp31_ = _g_object_ref0 (_tmp26_);
	result = _tmp31_;
	_g_object_unref0 (iptc_tags);
	_g_object_unref0 (xmp_tags);
	_g_object_unref0 (exif_tags);
	_g_object_unref0 (all_tags);
	(compare_func_target_destroy_notify == NULL) ? NULL : (compare_func_target_destroy_notify (compare_func_target), NULL);
	compare_func = NULL;
	compare_func_target = NULL;
	compare_func_target_destroy_notify = NULL;
	return result;
}

gchar*
photo_metadata_get_tag_label (PhotoMetadata* self,
                              const gchar* tag)
{
	const gchar* _tmp0_;
	gchar* _tmp1_;
	gchar* result;
	g_return_val_if_fail (self != NULL, NULL);
	g_return_val_if_fail (tag != NULL, NULL);
	_tmp0_ = gexiv2_metadata_get_tag_label (tag);
	_tmp1_ = g_strdup (_tmp0_);
	result = _tmp1_;
	return result;
}

gchar*
photo_metadata_get_tag_description (PhotoMetadata* self,
                                    const gchar* tag)
{
	const gchar* _tmp0_;
	gchar* _tmp1_;
	gchar* result;
	g_return_val_if_fail (self != NULL, NULL);
	g_return_val_if_fail (tag != NULL, NULL);
	_tmp0_ = gexiv2_metadata_get_tag_description (tag);
	_tmp1_ = g_strdup (_tmp0_);
	result = _tmp1_;
	return result;
}

gchar*
photo_metadata_get_string (PhotoMetadata* self,
                           const gchar* tag,
                           PrepareInputTextOptions options)
{
	GExiv2Metadata* _tmp0_;
	gchar* _tmp1_;
	gchar* _tmp2_;
	gchar* _tmp3_;
	gchar* _tmp4_;
	gchar* result;
	g_return_val_if_fail (self != NULL, NULL);
	g_return_val_if_fail (tag != NULL, NULL);
	_tmp0_ = self->priv->exiv2;
	_tmp1_ = gexiv2_metadata_get_tag_string (_tmp0_, tag);
	_tmp2_ = _tmp1_;
	_tmp3_ = prepare_input_text (_tmp2_, options, DEFAULT_USER_TEXT_INPUT_LENGTH);
	_tmp4_ = _tmp3_;
	_g_free0 (_tmp2_);
	result = _tmp4_;
	return result;
}

gchar*
photo_metadata_get_string_interpreted (PhotoMetadata* self,
                                       const gchar* tag,
                                       PrepareInputTextOptions options)
{
	GExiv2Metadata* _tmp0_;
	gchar* _tmp1_;
	gchar* _tmp2_;
	gchar* _tmp3_;
	gchar* _tmp4_;
	gchar* result;
	g_return_val_if_fail (self != NULL, NULL);
	g_return_val_if_fail (tag != NULL, NULL);
	_tmp0_ = self->priv->exiv2;
	_tmp1_ = gexiv2_metadata_get_tag_interpreted_string (_tmp0_, tag);
	_tmp2_ = _tmp1_;
	_tmp3_ = prepare_input_text (_tmp2_, options, DEFAULT_USER_TEXT_INPUT_LENGTH);
	_tmp4_ = _tmp3_;
	_g_free0 (_tmp2_);
	result = _tmp4_;
	return result;
}

gchar*
photo_metadata_get_first_string (PhotoMetadata* self,
                                 gchar** tags,
                                 gint tags_length1)
{
	gchar* result;
	g_return_val_if_fail (self != NULL, NULL);
	{
		gchar** tag_collection = NULL;
		gint tag_collection_length1 = 0;
		gint _tag_collection_size_ = 0;
		gint tag_it = 0;
		tag_collection = tags;
		tag_collection_length1 = tags_length1;
		for (tag_it = 0; tag_it < tag_collection_length1; tag_it = tag_it + 1) {
			gchar* _tmp0_;
			gchar* tag = NULL;
			_tmp0_ = g_strdup (tag_collection[tag_it]);
			tag = _tmp0_;
			{
				gchar* value = NULL;
				const gchar* _tmp1_;
				gchar* _tmp2_;
				const gchar* _tmp3_;
				_tmp1_ = tag;
				_tmp2_ = photo_metadata_get_string (self, _tmp1_, PHOTO_METADATA_PREPARE_STRING_OPTIONS);
				value = _tmp2_;
				_tmp3_ = value;
				if (_tmp3_ != NULL) {
					result = value;
					_g_free0 (tag);
					return result;
				}
				_g_free0 (value);
				_g_free0 (tag);
			}
		}
	}
	result = NULL;
	return result;
}

gchar*
photo_metadata_get_first_string_interpreted (PhotoMetadata* self,
                                             gchar** tags,
                                             gint tags_length1)
{
	gchar* result;
	g_return_val_if_fail (self != NULL, NULL);
	{
		gchar** tag_collection = NULL;
		gint tag_collection_length1 = 0;
		gint _tag_collection_size_ = 0;
		gint tag_it = 0;
		tag_collection = tags;
		tag_collection_length1 = tags_length1;
		for (tag_it = 0; tag_it < tag_collection_length1; tag_it = tag_it + 1) {
			gchar* _tmp0_;
			gchar* tag = NULL;
			_tmp0_ = g_strdup (tag_collection[tag_it]);
			tag = _tmp0_;
			{
				gchar* value = NULL;
				const gchar* _tmp1_;
				gchar* _tmp2_;
				const gchar* _tmp3_;
				_tmp1_ = tag;
				_tmp2_ = photo_metadata_get_string_interpreted (self, _tmp1_, PHOTO_METADATA_PREPARE_STRING_OPTIONS);
				value = _tmp2_;
				_tmp3_ = value;
				if (_tmp3_ != NULL) {
					result = value;
					_g_free0 (tag);
					return result;
				}
				_g_free0 (value);
				_g_free0 (tag);
			}
		}
	}
	result = NULL;
	return result;
}

GeeList*
photo_metadata_get_string_multiple (PhotoMetadata* self,
                                    const gchar* tag)
{
	gchar** values = NULL;
	GExiv2Metadata* _tmp0_;
	gchar** _tmp1_;
	gchar** _tmp2_;
	gint values_length1;
	gint _values_size_;
	gboolean _tmp3_ = FALSE;
	gchar** _tmp4_;
	gint _tmp4__length1;
	GeeList* list = NULL;
	GeeArrayList* _tmp6_;
	GeeHashSet* collection = NULL;
	GeeHashSet* _tmp7_;
	gchar** _tmp8_;
	gint _tmp8__length1;
	GeeList* _tmp20_ = NULL;
	GeeList* _tmp21_;
	gint _tmp22_;
	gint _tmp23_;
	GeeList* _tmp25_;
	GeeList* result;
	g_return_val_if_fail (self != NULL, NULL);
	g_return_val_if_fail (tag != NULL, NULL);
	_tmp0_ = self->priv->exiv2;
	_tmp2_ = _tmp1_ = gexiv2_metadata_get_tag_multiple (_tmp0_, tag);
	values = _tmp2_;
	values_length1 = _vala_array_length (_tmp1_);
	_values_size_ = values_length1;
	_tmp4_ = values;
	_tmp4__length1 = values_length1;
	if (_tmp4_ == NULL) {
		_tmp3_ = TRUE;
	} else {
		gchar** _tmp5_;
		gint _tmp5__length1;
		_tmp5_ = values;
		_tmp5__length1 = values_length1;
		_tmp3_ = _tmp5__length1 == 0;
	}
	if (_tmp3_) {
		result = NULL;
		values = (_vala_array_free (values, values_length1, (GDestroyNotify) g_free), NULL);
		return result;
	}
	_tmp6_ = gee_array_list_new (G_TYPE_STRING, (GBoxedCopyFunc) g_strdup, (GDestroyNotify) g_free, NULL, NULL, NULL);
	list = (GeeList*) _tmp6_;
	_tmp7_ = gee_hash_set_new (G_TYPE_STRING, (GBoxedCopyFunc) g_strdup, (GDestroyNotify) g_free, NULL, NULL, NULL, NULL, NULL, NULL);
	collection = _tmp7_;
	_tmp8_ = values;
	_tmp8__length1 = values_length1;
	{
		gchar** value_collection = NULL;
		gint value_collection_length1 = 0;
		gint _value_collection_size_ = 0;
		gint value_it = 0;
		value_collection = _tmp8_;
		value_collection_length1 = _tmp8__length1;
		for (value_it = 0; value_it < value_collection_length1; value_it = value_it + 1) {
			gchar* _tmp9_;
			gchar* value = NULL;
			_tmp9_ = g_strdup (value_collection[value_it]);
			value = _tmp9_;
			{
				gchar* prepped = NULL;
				const gchar* _tmp10_;
				gchar* _tmp11_;
				gboolean _tmp12_ = FALSE;
				const gchar* _tmp13_;
				_tmp10_ = value;
				_tmp11_ = prepare_input_text (_tmp10_, PHOTO_METADATA_PREPARE_STRING_OPTIONS, DEFAULT_USER_TEXT_INPUT_LENGTH);
				prepped = _tmp11_;
				_tmp13_ = prepped;
				if (_tmp13_ != NULL) {
					GeeHashSet* _tmp14_;
					const gchar* _tmp15_;
					_tmp14_ = collection;
					_tmp15_ = prepped;
					_tmp12_ = !gee_abstract_collection_contains ((GeeAbstractCollection*) _tmp14_, _tmp15_);
				} else {
					_tmp12_ = FALSE;
				}
				if (_tmp12_) {
					GeeList* _tmp16_;
					const gchar* _tmp17_;
					GeeHashSet* _tmp18_;
					const gchar* _tmp19_;
					_tmp16_ = list;
					_tmp17_ = prepped;
					gee_collection_add ((GeeCollection*) _tmp16_, _tmp17_);
					_tmp18_ = collection;
					_tmp19_ = prepped;
					gee_abstract_collection_add ((GeeAbstractCollection*) _tmp18_, _tmp19_);
				}
				_g_free0 (prepped);
				_g_free0 (value);
			}
		}
	}
	_tmp21_ = list;
	_tmp22_ = gee_collection_get_size ((GeeCollection*) _tmp21_);
	_tmp23_ = _tmp22_;
	if (_tmp23_ > 0) {
		GeeList* _tmp24_;
		_tmp24_ = list;
		_tmp20_ = _tmp24_;
	} else {
		_tmp20_ = NULL;
	}
	_tmp25_ = _g_object_ref0 (_tmp20_);
	result = _tmp25_;
	_g_object_unref0 (collection);
	_g_object_unref0 (list);
	values = (_vala_array_free (values, values_length1, (GDestroyNotify) g_free), NULL);
	return result;
}

GeeList*
photo_metadata_get_first_string_multiple (PhotoMetadata* self,
                                          gchar** tags,
                                          gint tags_length1)
{
	GeeList* result;
	g_return_val_if_fail (self != NULL, NULL);
	{
		gchar** tag_collection = NULL;
		gint tag_collection_length1 = 0;
		gint _tag_collection_size_ = 0;
		gint tag_it = 0;
		tag_collection = tags;
		tag_collection_length1 = tags_length1;
		for (tag_it = 0; tag_it < tag_collection_length1; tag_it = tag_it + 1) {
			gchar* _tmp0_;
			gchar* tag = NULL;
			_tmp0_ = g_strdup (tag_collection[tag_it]);
			tag = _tmp0_;
			{
				GeeList* values = NULL;
				const gchar* _tmp1_;
				GeeList* _tmp2_;
				gboolean _tmp3_ = FALSE;
				GeeList* _tmp4_;
				_tmp1_ = tag;
				_tmp2_ = photo_metadata_get_string_multiple (self, _tmp1_);
				values = _tmp2_;
				_tmp4_ = values;
				if (_tmp4_ != NULL) {
					GeeList* _tmp5_;
					gint _tmp6_;
					gint _tmp7_;
					_tmp5_ = values;
					_tmp6_ = gee_collection_get_size ((GeeCollection*) _tmp5_);
					_tmp7_ = _tmp6_;
					_tmp3_ = _tmp7_ > 0;
				} else {
					_tmp3_ = FALSE;
				}
				if (_tmp3_) {
					result = values;
					_g_free0 (tag);
					return result;
				}
				_g_object_unref0 (values);
				_g_free0 (tag);
			}
		}
	}
	result = NULL;
	return result;
}

void
photo_metadata_set_string (PhotoMetadata* self,
                           const gchar* tag,
                           const gchar* value,
                           PrepareInputTextOptions options)
{
	gchar* prepped = NULL;
	gchar* _tmp0_;
	const gchar* _tmp1_;
	GExiv2Metadata* _tmp2_;
	const gchar* _tmp3_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (tag != NULL);
	g_return_if_fail (value != NULL);
	_tmp0_ = prepare_input_text (value, options, DEFAULT_USER_TEXT_INPUT_LENGTH);
	prepped = _tmp0_;
	_tmp1_ = prepped;
	if (_tmp1_ == NULL) {
		g_warning ("PhotoMetadata.vala:401: Not setting tag %s to string %s: invalid UTF-8", tag, value);
		_g_free0 (prepped);
		return;
	}
	_tmp2_ = self->priv->exiv2;
	_tmp3_ = prepped;
	if (!gexiv2_metadata_set_tag_string (_tmp2_, tag, _tmp3_)) {
		const gchar* _tmp4_;
		_tmp4_ = self->priv->source_name;
		g_warning ("PhotoMetadata.vala:407: Unable to set tag %s to string %s from source " \
"%s", tag, value, _tmp4_);
	}
	_g_free0 (prepped);
}

static void
photo_metadata_set_all_generic (PhotoMetadata* self,
                                gchar** tags,
                                gint tags_length1,
                                PhotoMetadataSetOption option,
                                PhotoMetadataSetGenericValue setter,
                                gpointer setter_target)
{
	gboolean written = FALSE;
	gboolean _tmp4_ = FALSE;
	gboolean _tmp5_ = FALSE;
	g_return_if_fail (self != NULL);
	written = FALSE;
	{
		gchar** tag_collection = NULL;
		gint tag_collection_length1 = 0;
		gint _tag_collection_size_ = 0;
		gint tag_it = 0;
		tag_collection = tags;
		tag_collection_length1 = tags_length1;
		for (tag_it = 0; tag_it < tag_collection_length1; tag_it = tag_it + 1) {
			gchar* _tmp0_;
			gchar* tag = NULL;
			_tmp0_ = g_strdup (tag_collection[tag_it]);
			tag = _tmp0_;
			{
				gboolean _tmp1_ = FALSE;
				if (option == PHOTO_METADATA_SET_OPTION_ALL_DOMAINS) {
					_tmp1_ = TRUE;
				} else {
					const gchar* _tmp2_;
					_tmp2_ = tag;
					_tmp1_ = photo_metadata_has_domain (self, photo_metadata_get_tag_domain (_tmp2_));
				}
				if (_tmp1_) {
					const gchar* _tmp3_;
					_tmp3_ = tag;
					setter (_tmp3_, setter_target);
					written = TRUE;
				}
				_g_free0 (tag);
			}
		}
	}
	if (option == PHOTO_METADATA_SET_OPTION_AT_LEAST_DEFAULT_DOMAIN) {
		_tmp5_ = !written;
	} else {
		_tmp5_ = FALSE;
	}
	if (_tmp5_) {
		_tmp4_ = tags_length1 > 0;
	} else {
		_tmp4_ = FALSE;
	}
	if (_tmp4_) {
		MetadataDomain default_domain = 0;
		const gchar* _tmp6_;
		const gchar* _tmp7_;
		_tmp6_ = tags[0];
		default_domain = photo_metadata_get_tag_domain (_tmp6_);
		_tmp7_ = tags[0];
		setter (_tmp7_, setter_target);
		{
			gint ctr = 0;
			ctr = 1;
			{
				gboolean _tmp8_ = FALSE;
				_tmp8_ = TRUE;
				while (TRUE) {
					const gchar* _tmp10_;
					if (!_tmp8_) {
						gint _tmp9_;
						_tmp9_ = ctr;
						ctr = _tmp9_ + 1;
					}
					_tmp8_ = FALSE;
					if (!(ctr < tags_length1)) {
						break;
					}
					_tmp10_ = tags[ctr];
					if (photo_metadata_get_tag_domain (_tmp10_) == default_domain) {
						const gchar* _tmp11_;
						_tmp11_ = tags[ctr];
						setter (_tmp11_, setter_target);
					}
				}
			}
		}
	}
}

static Block3Data*
block3_data_ref (Block3Data* _data3_)
{
	g_atomic_int_inc (&_data3_->_ref_count_);
	return _data3_;
}

static void
block3_data_unref (void * _userdata_)
{
	Block3Data* _data3_;
	_data3_ = (Block3Data*) _userdata_;
	if (g_atomic_int_dec_and_test (&_data3_->_ref_count_)) {
		PhotoMetadata* self;
		self = _data3_->self;
		_g_free0 (_data3_->value);
		_media_metadata_unref0 (self);
		g_slice_free (Block3Data, _data3_);
	}
}

static void
__lambda4_ (Block3Data* _data3_,
            const gchar* tag)
{
	PhotoMetadata* self;
	self = _data3_->self;
	g_return_if_fail (tag != NULL);
	photo_metadata_set_string (self, tag, _data3_->value, PHOTO_METADATA_PREPARE_STRING_OPTIONS);
}

static void
___lambda4__photo_metadata_set_generic_value (const gchar* tag,
                                              gpointer self)
{
	__lambda4_ (self, tag);
}

void
photo_metadata_set_all_string (PhotoMetadata* self,
                               gchar** tags,
                               gint tags_length1,
                               const gchar* value,
                               PhotoMetadataSetOption option)
{
	Block3Data* _data3_;
	gchar* _tmp0_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (value != NULL);
	_data3_ = g_slice_new0 (Block3Data);
	_data3_->_ref_count_ = 1;
	_data3_->self = media_metadata_ref (self);
	_tmp0_ = g_strdup (value);
	_g_free0 (_data3_->value);
	_data3_->value = _tmp0_;
	photo_metadata_set_all_generic (self, tags, (gint) tags_length1, option, ___lambda4__photo_metadata_set_generic_value, _data3_);
	block3_data_unref (_data3_);
	_data3_ = NULL;
}

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

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

void
photo_metadata_set_string_multiple (PhotoMetadata* self,
                                    const gchar* tag,
                                    GeeCollection* collection)
{
	gchar** values = NULL;
	gchar** _tmp0_;
	gint values_length1;
	gint _values_size_;
	gchar** _tmp11_;
	gint _tmp11__length1;
	GExiv2Metadata* _tmp12_;
	gchar** _tmp13_;
	gint _tmp13__length1;
	g_return_if_fail (self != NULL);
	g_return_if_fail (tag != NULL);
	g_return_if_fail (collection != NULL);
	_tmp0_ = g_new0 (gchar*, 0 + 1);
	values = _tmp0_;
	values_length1 = 0;
	_values_size_ = values_length1;
	{
		GeeIterator* _value_it = NULL;
		GeeIterator* _tmp1_;
		_tmp1_ = gee_iterable_iterator ((GeeIterable*) collection);
		_value_it = _tmp1_;
		while (TRUE) {
			GeeIterator* _tmp2_;
			gchar* value = NULL;
			GeeIterator* _tmp3_;
			gpointer _tmp4_;
			gchar* prepped = NULL;
			const gchar* _tmp5_;
			gchar* _tmp6_;
			const gchar* _tmp7_;
			_tmp2_ = _value_it;
			if (!gee_iterator_next (_tmp2_)) {
				break;
			}
			_tmp3_ = _value_it;
			_tmp4_ = gee_iterator_get (_tmp3_);
			value = (gchar*) _tmp4_;
			_tmp5_ = value;
			_tmp6_ = prepare_input_text (_tmp5_, PHOTO_METADATA_PREPARE_STRING_OPTIONS, -1);
			prepped = _tmp6_;
			_tmp7_ = prepped;
			if (_tmp7_ != NULL) {
				const gchar* _tmp8_;
				gchar* _tmp9_;
				_tmp8_ = prepped;
				_tmp9_ = g_strdup (_tmp8_);
				_vala_array_add94 (&values, &values_length1, &_values_size_, _tmp9_);
			} else {
				const gchar* _tmp10_;
				_tmp10_ = value;
				g_warning ("PhotoMetadata.vala:448: Unable to set string %s to %s: invalid UTF-8", _tmp10_, tag);
			}
			_g_free0 (prepped);
			_g_free0 (value);
		}
		_g_object_unref0 (_value_it);
	}
	_tmp11_ = values;
	_tmp11__length1 = values_length1;
	if (_tmp11__length1 == 0) {
		values = (_vala_array_free (values, values_length1, (GDestroyNotify) g_free), NULL);
		return;
	}
	_vala_array_add95 (&values, &values_length1, &_values_size_, NULL);
	_tmp12_ = self->priv->exiv2;
	_tmp13_ = values;
	_tmp13__length1 = values_length1;
	if (!gexiv2_metadata_set_tag_multiple (_tmp12_, tag, _tmp13_)) {
		gchar** _tmp14_;
		gint _tmp14__length1;
		const gchar* _tmp15_;
		_tmp14_ = values;
		_tmp14__length1 = values_length1;
		_tmp15_ = self->priv->source_name;
		g_warning ("PhotoMetadata.vala:461: Unable to set %d strings to tag %s from source" \
" %s", _tmp14__length1, tag, _tmp15_);
	}
	values = (_vala_array_free (values, values_length1, (GDestroyNotify) g_free), NULL);
}

static Block4Data*
block4_data_ref (Block4Data* _data4_)
{
	g_atomic_int_inc (&_data4_->_ref_count_);
	return _data4_;
}

static void
block4_data_unref (void * _userdata_)
{
	Block4Data* _data4_;
	_data4_ = (Block4Data*) _userdata_;
	if (g_atomic_int_dec_and_test (&_data4_->_ref_count_)) {
		PhotoMetadata* self;
		self = _data4_->self;
		_g_object_unref0 (_data4_->values);
		_media_metadata_unref0 (self);
		g_slice_free (Block4Data, _data4_);
	}
}

static void
__lambda5_ (Block4Data* _data4_,
            const gchar* tag)
{
	PhotoMetadata* self;
	self = _data4_->self;
	g_return_if_fail (tag != NULL);
	photo_metadata_set_string_multiple (self, tag, _data4_->values);
}

static void
___lambda5__photo_metadata_set_generic_value (const gchar* tag,
                                              gpointer self)
{
	__lambda5_ (self, tag);
}

void
photo_metadata_set_all_string_multiple (PhotoMetadata* self,
                                        gchar** tags,
                                        gint tags_length1,
                                        GeeCollection* values,
                                        PhotoMetadataSetOption option)
{
	Block4Data* _data4_;
	GeeCollection* _tmp0_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (values != NULL);
	_data4_ = g_slice_new0 (Block4Data);
	_data4_->_ref_count_ = 1;
	_data4_->self = media_metadata_ref (self);
	_tmp0_ = _g_object_ref0 (values);
	_g_object_unref0 (_data4_->values);
	_data4_->values = _tmp0_;
	photo_metadata_set_all_generic (self, tags, (gint) tags_length1, option, ___lambda5__photo_metadata_set_generic_value, _data4_);
	block4_data_unref (_data4_);
	_data4_ = NULL;
}

gboolean
photo_metadata_get_long (PhotoMetadata* self,
                         const gchar* tag,
                         glong* value)
{
	glong _vala_value = 0L;
	GExiv2Metadata* _tmp0_;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	g_return_val_if_fail (tag != NULL, FALSE);
	if (!photo_metadata_has_tag (self, tag)) {
		_vala_value = (glong) 0;
		result = FALSE;
		if (value) {
			*value = _vala_value;
		}
		return result;
	}
	_tmp0_ = self->priv->exiv2;
	_vala_value = gexiv2_metadata_get_tag_long (_tmp0_, tag);
	result = TRUE;
	if (value) {
		*value = _vala_value;
	}
	return result;
}

gboolean
photo_metadata_get_first_long (PhotoMetadata* self,
                               gchar** tags,
                               gint tags_length1,
                               glong* value)
{
	glong _vala_value = 0L;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	{
		gchar** tag_collection = NULL;
		gint tag_collection_length1 = 0;
		gint _tag_collection_size_ = 0;
		gint tag_it = 0;
		tag_collection = tags;
		tag_collection_length1 = tags_length1;
		for (tag_it = 0; tag_it < tag_collection_length1; tag_it = tag_it + 1) {
			gchar* _tmp0_;
			gchar* tag = NULL;
			_tmp0_ = g_strdup (tag_collection[tag_it]);
			tag = _tmp0_;
			{
				const gchar* _tmp1_;
				glong _tmp2_ = 0L;
				gboolean _tmp3_;
				_tmp1_ = tag;
				_tmp3_ = photo_metadata_get_long (self, _tmp1_, &_tmp2_);
				_vala_value = _tmp2_;
				if (_tmp3_) {
					result = TRUE;
					_g_free0 (tag);
					if (value) {
						*value = _vala_value;
					}
					return result;
				}
				_g_free0 (tag);
			}
		}
	}
	_vala_value = (glong) 0;
	result = FALSE;
	if (value) {
		*value = _vala_value;
	}
	return result;
}

void
photo_metadata_set_long (PhotoMetadata* self,
                         const gchar* tag,
                         glong value)
{
	GExiv2Metadata* _tmp0_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (tag != NULL);
	_tmp0_ = self->priv->exiv2;
	if (!gexiv2_metadata_set_tag_long (_tmp0_, tag, value)) {
		const gchar* _tmp1_;
		_tmp1_ = self->priv->source_name;
		g_warning ("PhotoMetadata.vala:495: Unable to set tag %s to long %ld from source %" \
"s", tag, value, _tmp1_);
	}
}

static Block5Data*
block5_data_ref (Block5Data* _data5_)
{
	g_atomic_int_inc (&_data5_->_ref_count_);
	return _data5_;
}

static void
block5_data_unref (void * _userdata_)
{
	Block5Data* _data5_;
	_data5_ = (Block5Data*) _userdata_;
	if (g_atomic_int_dec_and_test (&_data5_->_ref_count_)) {
		PhotoMetadata* self;
		self = _data5_->self;
		_media_metadata_unref0 (self);
		g_slice_free (Block5Data, _data5_);
	}
}

static void
__lambda6_ (Block5Data* _data5_,
            const gchar* tag)
{
	PhotoMetadata* self;
	self = _data5_->self;
	g_return_if_fail (tag != NULL);
	photo_metadata_set_long (self, tag, _data5_->value);
}

static void
___lambda6__photo_metadata_set_generic_value (const gchar* tag,
                                              gpointer self)
{
	__lambda6_ (self, tag);
}

void
photo_metadata_set_all_long (PhotoMetadata* self,
                             gchar** tags,
                             gint tags_length1,
                             glong value,
                             PhotoMetadataSetOption option)
{
	Block5Data* _data5_;
	g_return_if_fail (self != NULL);
	_data5_ = g_slice_new0 (Block5Data);
	_data5_->_ref_count_ = 1;
	_data5_->self = media_metadata_ref (self);
	_data5_->value = value;
	photo_metadata_set_all_generic (self, tags, (gint) tags_length1, option, ___lambda6__photo_metadata_set_generic_value, _data5_);
	block5_data_unref (_data5_);
	_data5_ = NULL;
}

gboolean
photo_metadata_get_rational (PhotoMetadata* self,
                             const gchar* tag,
                             MetadataRational* rational)
{
	MetadataRational _vala_rational = {0};
	gint numerator = 0;
	gint denominator = 0;
	gboolean _result_ = FALSE;
	GExiv2Metadata* _tmp0_;
	gint _tmp1_ = 0;
	gint _tmp2_ = 0;
	gboolean _tmp3_;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	g_return_val_if_fail (tag != NULL, FALSE);
	_tmp0_ = self->priv->exiv2;
	_tmp3_ = gexiv2_metadata_get_exif_tag_rational (_tmp0_, tag, &_tmp1_, &_tmp2_);
	numerator = _tmp1_;
	denominator = _tmp2_;
	_result_ = _tmp3_;
	metadata_rational_init (&_vala_rational, numerator, denominator);
	result = _result_;
	if (rational) {
		*rational = _vala_rational;
	}
	return result;
}

gboolean
photo_metadata_get_first_rational (PhotoMetadata* self,
                                   gchar** tags,
                                   gint tags_length1,
                                   MetadataRational* rational)
{
	MetadataRational _vala_rational = {0};
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	{
		gchar** tag_collection = NULL;
		gint tag_collection_length1 = 0;
		gint _tag_collection_size_ = 0;
		gint tag_it = 0;
		tag_collection = tags;
		tag_collection_length1 = tags_length1;
		for (tag_it = 0; tag_it < tag_collection_length1; tag_it = tag_it + 1) {
			gchar* _tmp0_;
			gchar* tag = NULL;
			_tmp0_ = g_strdup (tag_collection[tag_it]);
			tag = _tmp0_;
			{
				const gchar* _tmp1_;
				MetadataRational _tmp2_ = {0};
				gboolean _tmp3_;
				_tmp1_ = tag;
				_tmp3_ = photo_metadata_get_rational (self, _tmp1_, &_tmp2_);
				_vala_rational = _tmp2_;
				if (_tmp3_) {
					result = TRUE;
					_g_free0 (tag);
					if (rational) {
						*rational = _vala_rational;
					}
					return result;
				}
				_g_free0 (tag);
			}
		}
	}
	metadata_rational_init (&_vala_rational, 0, 0);
	result = FALSE;
	if (rational) {
		*rational = _vala_rational;
	}
	return result;
}

void
photo_metadata_set_rational (PhotoMetadata* self,
                             const gchar* tag,
                             MetadataRational* rational)
{
	GExiv2Metadata* _tmp0_;
	MetadataRational _tmp1_;
	MetadataRational _tmp2_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (tag != NULL);
	g_return_if_fail (rational != NULL);
	_tmp0_ = self->priv->exiv2;
	_tmp1_ = *rational;
	_tmp2_ = *rational;
	if (!gexiv2_metadata_set_exif_tag_rational (_tmp0_, tag, _tmp1_.numerator, _tmp2_.denominator)) {
		gchar* _tmp3_;
		gchar* _tmp4_;
		const gchar* _tmp5_;
		_tmp3_ = metadata_rational_to_string (rational);
		_tmp4_ = _tmp3_;
		_tmp5_ = self->priv->source_name;
		g_warning ("PhotoMetadata.vala:526: Unable to set tag %s to rational %s from sourc" \
"e %s", tag, _tmp4_, _tmp5_);
		_g_free0 (_tmp4_);
	}
}

static Block6Data*
block6_data_ref (Block6Data* _data6_)
{
	g_atomic_int_inc (&_data6_->_ref_count_);
	return _data6_;
}

static void
block6_data_unref (void * _userdata_)
{
	Block6Data* _data6_;
	_data6_ = (Block6Data*) _userdata_;
	if (g_atomic_int_dec_and_test (&_data6_->_ref_count_)) {
		PhotoMetadata* self;
		self = _data6_->self;
		_media_metadata_unref0 (self);
		g_slice_free (Block6Data, _data6_);
	}
}

static void
__lambda7_ (Block6Data* _data6_,
            const gchar* tag)
{
	PhotoMetadata* self;
	MetadataRational _tmp0_;
	self = _data6_->self;
	g_return_if_fail (tag != NULL);
	_tmp0_ = _data6_->rational;
	photo_metadata_set_rational (self, tag, &_tmp0_);
}

static void
___lambda7__photo_metadata_set_generic_value (const gchar* tag,
                                              gpointer self)
{
	__lambda7_ (self, tag);
}

void
photo_metadata_set_all_rational (PhotoMetadata* self,
                                 gchar** tags,
                                 gint tags_length1,
                                 MetadataRational* rational,
                                 PhotoMetadataSetOption option)
{
	Block6Data* _data6_;
	MetadataRational _tmp0_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (rational != NULL);
	_data6_ = g_slice_new0 (Block6Data);
	_data6_->_ref_count_ = 1;
	_data6_->self = media_metadata_ref (self);
	_tmp0_ = *rational;
	_data6_->rational = _tmp0_;
	photo_metadata_set_all_generic (self, tags, (gint) tags_length1, option, ___lambda7__photo_metadata_set_generic_value, _data6_);
	block6_data_unref (_data6_);
	_data6_ = NULL;
}

MetadataDateTime*
photo_metadata_get_date_time (PhotoMetadata* self,
                              const gchar* tag)
{
	gchar* value = NULL;
	gchar* _tmp0_;
	const gchar* _tmp1_;
	GError* _inner_error0_ = NULL;
	MetadataDateTime* result;
	g_return_val_if_fail (self != NULL, NULL);
	g_return_val_if_fail (tag != NULL, NULL);
	_tmp0_ = photo_metadata_get_string (self, tag, PHOTO_METADATA_PREPARE_STRING_OPTIONS);
	value = _tmp0_;
	_tmp1_ = value;
	if (_tmp1_ == NULL) {
		result = NULL;
		_g_free0 (value);
		return result;
	}
	{
		switch (photo_metadata_get_tag_domain (tag)) {
			case METADATA_DOMAIN_XMP:
			{
				MetadataDateTime* _tmp2_ = NULL;
				const gchar* _tmp3_;
				MetadataDateTime* _tmp4_;
				MetadataDateTime* _tmp5_;
				_tmp3_ = value;
				_tmp4_ = metadata_date_time_new_from_xmp (_tmp3_, &_inner_error0_);
				_tmp2_ = _tmp4_;
				if (G_UNLIKELY (_inner_error0_ != NULL)) {
					goto __catch0_g_error;
				}
				_tmp5_ = _tmp2_;
				_tmp2_ = NULL;
				result = _tmp5_;
				_metadata_date_time_unref0 (_tmp2_);
				_g_free0 (value);
				return result;
			}
			case METADATA_DOMAIN_IPTC:
			{
				result = NULL;
				_g_free0 (value);
				return result;
			}
			default:
			case METADATA_DOMAIN_EXIF:
			{
				MetadataDateTime* _tmp6_ = NULL;
				const gchar* _tmp7_;
				MetadataDateTime* _tmp8_;
				MetadataDateTime* _tmp9_;
				_tmp7_ = value;
				_tmp8_ = metadata_date_time_new_from_exif (_tmp7_, &_inner_error0_);
				_tmp6_ = _tmp8_;
				if (G_UNLIKELY (_inner_error0_ != NULL)) {
					goto __catch0_g_error;
				}
				_tmp9_ = _tmp6_;
				_tmp6_ = NULL;
				result = _tmp9_;
				_metadata_date_time_unref0 (_tmp6_);
				_g_free0 (value);
				return result;
			}
		}
	}
	goto __finally0;
	__catch0_g_error:
	{
		GError* err = NULL;
		const gchar* _tmp10_;
		GError* _tmp11_;
		const gchar* _tmp12_;
		err = _inner_error0_;
		_inner_error0_ = NULL;
		_tmp10_ = self->priv->source_name;
		_tmp11_ = err;
		_tmp12_ = _tmp11_->message;
		g_warning ("PhotoMetadata.vala:557: Unable to read date/time %s from source %s: %s", tag, _tmp10_, _tmp12_);
		result = NULL;
		_g_error_free0 (err);
		_g_free0 (value);
		return result;
	}
	__finally0:
	_g_free0 (value);
	g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error0_->message, g_quark_to_string (_inner_error0_->domain), _inner_error0_->code);
	g_clear_error (&_inner_error0_);
	return NULL;
}

MetadataDateTime*
photo_metadata_get_first_date_time (PhotoMetadata* self,
                                    gchar** tags,
                                    gint tags_length1)
{
	MetadataDateTime* result;
	g_return_val_if_fail (self != NULL, NULL);
	{
		gchar** tag_collection = NULL;
		gint tag_collection_length1 = 0;
		gint _tag_collection_size_ = 0;
		gint tag_it = 0;
		tag_collection = tags;
		tag_collection_length1 = tags_length1;
		for (tag_it = 0; tag_it < tag_collection_length1; tag_it = tag_it + 1) {
			gchar* _tmp0_;
			gchar* tag = NULL;
			_tmp0_ = g_strdup (tag_collection[tag_it]);
			tag = _tmp0_;
			{
				MetadataDateTime* date_time = NULL;
				const gchar* _tmp1_;
				MetadataDateTime* _tmp2_;
				MetadataDateTime* _tmp3_;
				_tmp1_ = tag;
				_tmp2_ = photo_metadata_get_date_time (self, _tmp1_);
				date_time = _tmp2_;
				_tmp3_ = date_time;
				if (_tmp3_ != NULL) {
					result = date_time;
					_g_free0 (tag);
					return result;
				}
				_metadata_date_time_unref0 (date_time);
				_g_free0 (tag);
			}
		}
	}
	result = NULL;
	return result;
}

void
photo_metadata_set_date_time (PhotoMetadata* self,
                              const gchar* tag,
                              MetadataDateTime* date_time)
{
	g_return_if_fail (self != NULL);
	g_return_if_fail (tag != NULL);
	g_return_if_fail (date_time != NULL);
	switch (photo_metadata_get_tag_domain (tag)) {
		case METADATA_DOMAIN_EXIF:
		{
			gchar* _tmp0_;
			gchar* _tmp1_;
			_tmp0_ = metadata_date_time_get_exif_label (date_time);
			_tmp1_ = _tmp0_;
			photo_metadata_set_string (self, tag, _tmp1_, PHOTO_METADATA_PREPARE_STRING_OPTIONS);
			_g_free0 (_tmp1_);
			break;
		}
		case METADATA_DOMAIN_XMP:
		{
			gchar* _tmp2_;
			gchar* _tmp3_;
			_tmp2_ = metadata_date_time_get_xmp_label (date_time);
			_tmp3_ = _tmp2_;
			photo_metadata_set_string (self, tag, _tmp3_, PHOTO_METADATA_PREPARE_STRING_OPTIONS);
			_g_free0 (_tmp3_);
			break;
		}
		default:
		case METADATA_DOMAIN_IPTC:
		{
			const gchar* _tmp4_;
			GEnumValue* _tmp5_;
			_tmp4_ = self->priv->source_name;
			_tmp5_ = g_enum_get_value (g_type_class_ref (TYPE_METADATA_DOMAIN), photo_metadata_get_tag_domain (tag));
			g_warning ("PhotoMetadata.vala:586: Cannot set date/time for %s from source %s: un" \
"supported metadata domain %s", tag, _tmp4_, (_tmp5_ != NULL) ? _tmp5_->value_name : NULL);
			break;
		}
	}
}

static gpointer
_metadata_date_time_ref0 (gpointer self)
{
	return self ? metadata_date_time_ref (self) : NULL;
}

static Block7Data*
block7_data_ref (Block7Data* _data7_)
{
	g_atomic_int_inc (&_data7_->_ref_count_);
	return _data7_;
}

static void
block7_data_unref (void * _userdata_)
{
	Block7Data* _data7_;
	_data7_ = (Block7Data*) _userdata_;
	if (g_atomic_int_dec_and_test (&_data7_->_ref_count_)) {
		PhotoMetadata* self;
		self = _data7_->self;
		_metadata_date_time_unref0 (_data7_->date_time);
		_media_metadata_unref0 (self);
		g_slice_free (Block7Data, _data7_);
	}
}

static void
__lambda8_ (Block7Data* _data7_,
            const gchar* tag)
{
	PhotoMetadata* self;
	self = _data7_->self;
	g_return_if_fail (tag != NULL);
	photo_metadata_set_date_time (self, tag, _data7_->date_time);
}

static void
___lambda8__photo_metadata_set_generic_value (const gchar* tag,
                                              gpointer self)
{
	__lambda8_ (self, tag);
}

void
photo_metadata_set_all_date_time (PhotoMetadata* self,
                                  gchar** tags,
                                  gint tags_length1,
                                  MetadataDateTime* date_time,
                                  PhotoMetadataSetOption option)
{
	Block7Data* _data7_;
	MetadataDateTime* _tmp0_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (date_time != NULL);
	_data7_ = g_slice_new0 (Block7Data);
	_data7_->_ref_count_ = 1;
	_data7_->self = media_metadata_ref (self);
	_tmp0_ = _metadata_date_time_ref0 (date_time);
	_metadata_date_time_unref0 (_data7_->date_time);
	_data7_->date_time = _tmp0_;
	photo_metadata_set_all_generic (self, tags, (gint) tags_length1, option, ___lambda8__photo_metadata_set_generic_value, _data7_);
	block7_data_unref (_data7_);
	_data7_ = NULL;
}

guint8*
photo_metadata_flatten_exif (PhotoMetadata* self,
                             gboolean include_preview,
                             gint* result_length1)
{
	ExifData* _tmp0_;
	guchar* thumbnail = NULL;
	ExifData* _tmp2_;
	guchar* _tmp3_;
	guint thumbnail_size = 0U;
	ExifData* _tmp4_;
	guint8* flattened = NULL;
	gint flattened_length1;
	gint _flattened_size_;
	guchar* saved_data = NULL;
	guint saved_size = 0U;
	ExifData* _tmp7_;
	gboolean _tmp8_ = FALSE;
	ExifData* _tmp16_;
	guchar* _tmp17_;
	ExifData* _tmp18_;
	guint8* _tmp19_;
	gint _tmp19__length1;
	guint8* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->exif;
	if (_tmp0_ == NULL) {
		guint8* _tmp1_;
		gint _tmp1__length1;
		_tmp1_ = NULL;
		_tmp1__length1 = 0;
		if (result_length1) {
			*result_length1 = _tmp1__length1;
		}
		result = _tmp1_;
		return result;
	}
	_tmp2_ = self->priv->exif;
	_tmp3_ = _tmp2_->data;
	thumbnail = _tmp3_;
	_tmp4_ = self->priv->exif;
	thumbnail_size = _tmp4_->size;
	if (!include_preview) {
		ExifData* _tmp5_;
		ExifData* _tmp6_;
		_tmp5_ = self->priv->exif;
		_tmp5_->data = NULL;
		_tmp6_ = self->priv->exif;
		_tmp6_->size = (guint) 0;
	}
	flattened = NULL;
	flattened_length1 = 0;
	_flattened_size_ = flattened_length1;
	saved_data = NULL;
	saved_size = (guint) 0;
	_tmp7_ = self->priv->exif;
	exif_data_save_data (_tmp7_, &saved_data, &saved_size);
	if (saved_size > ((guint) 0)) {
		guchar* _tmp9_;
		_tmp9_ = saved_data;
		_tmp8_ = _tmp9_ != NULL;
	} else {
		_tmp8_ = FALSE;
	}
	if (_tmp8_) {
		guint8* _tmp10_;
		guint8* _tmp11_;
		gint _tmp11__length1;
		guchar* _tmp12_;
		ExifMem* _tmp13_;
		ExifMem* _tmp14_;
		guchar* _tmp15_;
		_tmp10_ = g_new0 (guint8, saved_size);
		flattened = (g_free (flattened), NULL);
		flattened = _tmp10_;
		flattened_length1 = saved_size;
		_flattened_size_ = flattened_length1;
		_tmp11_ = flattened;
		_tmp11__length1 = flattened_length1;
		_tmp12_ = saved_data;
		memcpy (_tmp11_, _tmp12_, (gsize) saved_size);
		_tmp13_ = exif_mem_new_default ();
		_tmp14_ = _tmp13_;
		_tmp15_ = saved_data;
		exif_mem_free (_tmp14_, _tmp15_);
		_exif_mem_unref0 (_tmp14_);
	}
	_tmp16_ = self->priv->exif;
	_tmp17_ = thumbnail;
	_tmp16_->data = _tmp17_;
	_tmp18_ = self->priv->exif;
	_tmp18_->size = thumbnail_size;
	_tmp19_ = flattened;
	_tmp19__length1 = flattened_length1;
	if (result_length1) {
		*result_length1 = _tmp19__length1;
	}
	result = _tmp19_;
	return result;
}

static guint8*
_vala_array_dup15 (guint8* self,
                   gssize length)
{
	if (length > 0) {
		return _vala_memdup2 (self, length * sizeof (guint8));
	}
	return NULL;
}

guint8*
photo_metadata_flatten_exif_preview (PhotoMetadata* self,
                                     gint* result_length1)
{
	guchar* buffer = NULL;
	gint buffer_length1 = 0;
	gint _buffer_size_ = 0;
	guchar* _tmp0_ = NULL;
	gint _tmp0__length1 = 0;
	gint __tmp0__size_ = 0;
	GExiv2Metadata* _tmp1_;
	guint8* _tmp2_ = NULL;
	gint _tmp3_ = 0;
	gboolean _tmp4_;
	guint8* _tmp6_;
	gint _tmp6__length1;
	guint8* _tmp7_;
	gint _tmp7__length1;
	guint8* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp1_ = self->priv->exiv2;
	_tmp4_ = gexiv2_metadata_get_exif_thumbnail (_tmp1_, &_tmp2_, &_tmp3_);
	buffer = (g_free (buffer), NULL);
	buffer = _tmp2_;
	buffer_length1 = _tmp3_;
	_buffer_size_ = buffer_length1;
	if (_tmp4_) {
		guchar* _tmp5_;
		gint _tmp5__length1;
		_tmp5_ = buffer;
		_tmp5__length1 = buffer_length1;
		_tmp0_ = _tmp5_;
		_tmp0__length1 = _tmp5__length1;
		__tmp0__size_ = _tmp0__length1;
	} else {
		_tmp0_ = NULL;
		_tmp0__length1 = 0;
		__tmp0__size_ = _tmp0__length1;
	}
	_tmp6_ = (_tmp0_ != NULL) ? _vala_array_dup15 (_tmp0_, _tmp0__length1) : _tmp0_;
	_tmp6__length1 = _tmp0__length1;
	_tmp7_ = _tmp6_;
	_tmp7__length1 = _tmp6__length1;
	if (result_length1) {
		*result_length1 = _tmp7__length1;
	}
	result = _tmp7_;
	buffer = (g_free (buffer), NULL);
	return result;
}

guint
photo_metadata_get_preview_count (PhotoMetadata* self)
{
	GExiv2PreviewProperties** props = NULL;
	GExiv2Metadata* _tmp0_;
	GExiv2PreviewProperties** _tmp1_;
	GExiv2PreviewProperties** _tmp2_;
	gint props_length1;
	gint _props_size_;
	gint _tmp3_ = 0;
	GExiv2PreviewProperties** _tmp4_;
	gint _tmp4__length1;
	guint result;
	g_return_val_if_fail (self != NULL, 0U);
	_tmp0_ = self->priv->exiv2;
	_tmp2_ = _tmp1_ = gexiv2_metadata_get_preview_properties (_tmp0_);
	props = _tmp2_;
	props_length1 = _vala_array_length (_tmp1_);
	_props_size_ = props_length1;
	_tmp4_ = props;
	_tmp4__length1 = props_length1;
	if (_tmp4_ != NULL) {
		GExiv2PreviewProperties** _tmp5_;
		gint _tmp5__length1;
		_tmp5_ = props;
		_tmp5__length1 = props_length1;
		_tmp3_ = _tmp5__length1;
	} else {
		_tmp3_ = 0;
	}
	result = (guint) _tmp3_;
	return result;
}

PhotoPreview*
photo_metadata_get_preview (PhotoMetadata* self,
                            guint number)
{
	GExiv2PreviewProperties** props = NULL;
	GExiv2Metadata* _tmp0_;
	GExiv2PreviewProperties** _tmp1_;
	GExiv2PreviewProperties** _tmp2_;
	gint props_length1;
	gint _props_size_;
	gboolean _tmp3_ = FALSE;
	GExiv2PreviewProperties** _tmp4_;
	gint _tmp4__length1;
	const gchar* _tmp6_;
	GExiv2PreviewProperties** _tmp7_;
	gint _tmp7__length1;
	GExiv2PreviewProperties* _tmp8_;
	PhotoMetadataInternalPhotoPreview* _tmp9_;
	PhotoPreview* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->exiv2;
	_tmp2_ = _tmp1_ = gexiv2_metadata_get_preview_properties (_tmp0_);
	props = _tmp2_;
	props_length1 = _vala_array_length (_tmp1_);
	_props_size_ = props_length1;
	_tmp4_ = props;
	_tmp4__length1 = props_length1;
	if (_tmp4_ == NULL) {
		_tmp3_ = TRUE;
	} else {
		GExiv2PreviewProperties** _tmp5_;
		gint _tmp5__length1;
		_tmp5_ = props;
		_tmp5__length1 = props_length1;
		_tmp3_ = ((guint) _tmp5__length1) <= number;
	}
	if (_tmp3_) {
		result = NULL;
		return result;
	}
	_tmp6_ = self->priv->source_name;
	_tmp7_ = props;
	_tmp7__length1 = props_length1;
	_tmp8_ = _tmp7_[number];
	_tmp9_ = photo_metadata_internal_photo_preview_new (self, _tmp6_, number, _tmp8_);
	result = (PhotoPreview*) _tmp9_;
	return result;
}

void
photo_metadata_remove_exif_thumbnail (PhotoMetadata* self)
{
	GExiv2Metadata* _tmp0_;
	ExifData* _tmp1_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->exiv2;
	gexiv2_metadata_erase_exif_thumbnail (_tmp0_);
	_tmp1_ = self->priv->exif;
	if (_tmp1_ != NULL) {
		ExifMem* _tmp2_;
		ExifMem* _tmp3_;
		ExifData* _tmp4_;
		guchar* _tmp5_;
		ExifData* _tmp6_;
		ExifData* _tmp7_;
		_tmp2_ = exif_mem_new_default ();
		_tmp3_ = _tmp2_;
		_tmp4_ = self->priv->exif;
		_tmp5_ = _tmp4_->data;
		exif_mem_free (_tmp3_, _tmp5_);
		_exif_mem_unref0 (_tmp3_);
		_tmp6_ = self->priv->exif;
		_tmp6_->data = NULL;
		_tmp7_ = self->priv->exif;
		_tmp7_->size = (guint) 0;
	}
}

void
photo_metadata_remove_tag (PhotoMetadata* self,
                           const gchar* tag)
{
	GExiv2Metadata* _tmp0_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (tag != NULL);
	_tmp0_ = self->priv->exiv2;
	gexiv2_metadata_clear_tag (_tmp0_, tag);
}

void
photo_metadata_remove_tags (PhotoMetadata* self,
                            gchar** tags,
                            gint tags_length1)
{
	g_return_if_fail (self != NULL);
	{
		gchar** tag_collection = NULL;
		gint tag_collection_length1 = 0;
		gint _tag_collection_size_ = 0;
		gint tag_it = 0;
		tag_collection = tags;
		tag_collection_length1 = tags_length1;
		for (tag_it = 0; tag_it < tag_collection_length1; tag_it = tag_it + 1) {
			gchar* _tmp0_;
			gchar* tag = NULL;
			_tmp0_ = g_strdup (tag_collection[tag_it]);
			tag = _tmp0_;
			{
				const gchar* _tmp1_;
				_tmp1_ = tag;
				photo_metadata_remove_tag (self, _tmp1_);
				_g_free0 (tag);
			}
		}
	}
}

void
photo_metadata_clear_domain (PhotoMetadata* self,
                             MetadataDomain domain)
{
	g_return_if_fail (self != NULL);
	switch (domain) {
		case METADATA_DOMAIN_EXIF:
		{
			GExiv2Metadata* _tmp0_;
			_tmp0_ = self->priv->exiv2;
			gexiv2_metadata_clear_exif (_tmp0_);
			break;
		}
		case METADATA_DOMAIN_XMP:
		{
			GExiv2Metadata* _tmp1_;
			_tmp1_ = self->priv->exiv2;
			gexiv2_metadata_clear_xmp (_tmp1_);
			break;
		}
		case METADATA_DOMAIN_IPTC:
		{
			GExiv2Metadata* _tmp2_;
			_tmp2_ = self->priv->exiv2;
			gexiv2_metadata_clear_iptc (_tmp2_);
			break;
		}
		default:
		break;
	}
}

void
photo_metadata_clear (PhotoMetadata* self)
{
	GExiv2Metadata* _tmp0_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->exiv2;
	gexiv2_metadata_clear (_tmp0_);
}

MetadataDateTime*
photo_metadata_get_modification_date_time (PhotoMetadata* self)
{
	gchar** _tmp0_;
	gint _tmp0__length1;
	MetadataDateTime* _tmp1_;
	MetadataDateTime* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = photo_metadata_date_int64ags;
	_tmp0__length1 = photo_metadata_date_int64ags_length1;
	_tmp1_ = photo_metadata_get_first_date_time (self, _tmp0_, (gint) _tmp0__length1);
	result = _tmp1_;
	return result;
}

void
photo_metadata_set_modification_date_time (PhotoMetadata* self,
                                           MetadataDateTime* date_time,
                                           PhotoMetadataSetOption option)
{
	g_return_if_fail (self != NULL);
	if (date_time != NULL) {
		gchar** _tmp0_;
		gint _tmp0__length1;
		_tmp0_ = photo_metadata_date_int64ags;
		_tmp0__length1 = photo_metadata_date_int64ags_length1;
		photo_metadata_set_all_date_time (self, _tmp0_, (gint) _tmp0__length1, date_time, option);
	} else {
		gchar** _tmp1_;
		gint _tmp1__length1;
		_tmp1_ = photo_metadata_date_int64ags;
		_tmp1__length1 = photo_metadata_date_int64ags_length1;
		photo_metadata_remove_tags (self, _tmp1_, (gint) _tmp1__length1);
	}
}

MetadataDateTime*
photo_metadata_get_exposure_date_time (PhotoMetadata* self)
{
	gchar** _tmp0_;
	gint _tmp0__length1;
	MetadataDateTime* _tmp1_;
	MetadataDateTime* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = photo_metadata_exposure_date_int64ags;
	_tmp0__length1 = photo_metadata_exposure_date_int64ags_length1;
	_tmp1_ = photo_metadata_get_first_date_time (self, _tmp0_, (gint) _tmp0__length1);
	result = _tmp1_;
	return result;
}

void
photo_metadata_set_exposure_date_time (PhotoMetadata* self,
                                       MetadataDateTime* date_time,
                                       PhotoMetadataSetOption option)
{
	g_return_if_fail (self != NULL);
	if (date_time != NULL) {
		gchar** _tmp0_;
		gint _tmp0__length1;
		_tmp0_ = photo_metadata_exposure_date_int64ags;
		_tmp0__length1 = photo_metadata_exposure_date_int64ags_length1;
		photo_metadata_set_all_date_time (self, _tmp0_, (gint) _tmp0__length1, date_time, option);
	} else {
		gchar** _tmp1_;
		gint _tmp1__length1;
		_tmp1_ = photo_metadata_exposure_date_int64ags;
		_tmp1__length1 = photo_metadata_exposure_date_int64ags_length1;
		photo_metadata_remove_tags (self, _tmp1_, (gint) _tmp1__length1);
	}
}

MetadataDateTime*
photo_metadata_get_digitized_date_time (PhotoMetadata* self)
{
	gchar** _tmp0_;
	gint _tmp0__length1;
	MetadataDateTime* _tmp1_;
	MetadataDateTime* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = photo_metadata_digitized_date_int64ags;
	_tmp0__length1 = photo_metadata_digitized_date_int64ags_length1;
	_tmp1_ = photo_metadata_get_first_date_time (self, _tmp0_, (gint) _tmp0__length1);
	result = _tmp1_;
	return result;
}

void
photo_metadata_set_digitized_date_time (PhotoMetadata* self,
                                        MetadataDateTime* date_time,
                                        PhotoMetadataSetOption option)
{
	g_return_if_fail (self != NULL);
	if (date_time != NULL) {
		gchar** _tmp0_;
		gint _tmp0__length1;
		_tmp0_ = photo_metadata_digitized_date_int64ags;
		_tmp0__length1 = photo_metadata_digitized_date_int64ags_length1;
		photo_metadata_set_all_date_time (self, _tmp0_, (gint) _tmp0__length1, date_time, option);
	} else {
		gchar** _tmp1_;
		gint _tmp1__length1;
		_tmp1_ = photo_metadata_digitized_date_int64ags;
		_tmp1__length1 = photo_metadata_digitized_date_int64ags_length1;
		photo_metadata_remove_tags (self, _tmp1_, (gint) _tmp1__length1);
	}
}

static MetadataDateTime*
photo_metadata_real_get_creation_date_time (MediaMetadata* base)
{
	PhotoMetadata * self;
	MetadataDateTime* creation = NULL;
	MetadataDateTime* _tmp0_;
	MetadataDateTime* _tmp1_;
	MetadataDateTime* result;
	self = (PhotoMetadata*) base;
	_tmp0_ = photo_metadata_get_exposure_date_time (self);
	creation = _tmp0_;
	_tmp1_ = creation;
	if (_tmp1_ == NULL) {
		MetadataDateTime* _tmp2_;
		_tmp2_ = photo_metadata_get_digitized_date_time (self);
		_metadata_date_time_unref0 (creation);
		creation = _tmp2_;
	}
	result = creation;
	return result;
}

static gpointer
_dimensions_dup0 (gpointer self)
{
	return self ? dimensions_dup (self) : NULL;
}

Dimensions*
photo_metadata_get_pixel_dimensions (PhotoMetadata* self)
{
	gchar** _tmp0_;
	gint _tmp0__length1;
	gchar** _tmp1_;
	gint _tmp1__length1;
	Dimensions* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = photo_metadata_width_tags;
	_tmp0__length1 = photo_metadata_width_tags_length1;
	_tmp1_ = photo_metadata_height_tags;
	_tmp1__length1 = photo_metadata_height_tags_length1;
	_vala_assert (_tmp0__length1 == _tmp1__length1, "width_tags.length == height_tags.length");
	{
		gint ctr = 0;
		ctr = 0;
		{
			gboolean _tmp2_ = FALSE;
			_tmp2_ = TRUE;
			while (TRUE) {
				gchar** _tmp4_;
				gint _tmp4__length1;
				glong width = 0L;
				gchar** _tmp5_;
				gint _tmp5__length1;
				const gchar* _tmp6_;
				glong _tmp7_ = 0L;
				gboolean _tmp8_;
				glong height = 0L;
				gchar** _tmp9_;
				gint _tmp9__length1;
				const gchar* _tmp10_;
				glong _tmp11_ = 0L;
				gboolean _tmp12_;
				Dimensions _tmp13_ = {0};
				Dimensions* _tmp14_;
				if (!_tmp2_) {
					gint _tmp3_;
					_tmp3_ = ctr;
					ctr = _tmp3_ + 1;
				}
				_tmp2_ = FALSE;
				_tmp4_ = photo_metadata_width_tags;
				_tmp4__length1 = photo_metadata_width_tags_length1;
				if (!(ctr < _tmp4__length1)) {
					break;
				}
				_tmp5_ = photo_metadata_width_tags;
				_tmp5__length1 = photo_metadata_width_tags_length1;
				_tmp6_ = _tmp5_[ctr];
				_tmp8_ = photo_metadata_get_long (self, _tmp6_, &_tmp7_);
				width = _tmp7_;
				if (!_tmp8_) {
					continue;
				}
				_tmp9_ = photo_metadata_height_tags;
				_tmp9__length1 = photo_metadata_height_tags_length1;
				_tmp10_ = _tmp9_[ctr];
				_tmp12_ = photo_metadata_get_long (self, _tmp10_, &_tmp11_);
				height = _tmp11_;
				if (!_tmp12_) {
					continue;
				}
				dimensions_init (&_tmp13_, (gint) width, (gint) height);
				_tmp14_ = _dimensions_dup0 (&_tmp13_);
				result = _tmp14_;
				return result;
			}
		}
	}
	result = NULL;
	return result;
}

void
photo_metadata_set_pixel_dimensions (PhotoMetadata* self,
                                     Dimensions* dim,
                                     PhotoMetadataSetOption option)
{
	g_return_if_fail (self != NULL);
	if (dim != NULL) {
		gchar** _tmp0_;
		gint _tmp0__length1;
		gchar** _tmp1_;
		gint _tmp1__length1;
		_tmp0_ = photo_metadata_width_tags;
		_tmp0__length1 = photo_metadata_width_tags_length1;
		photo_metadata_set_all_long (self, _tmp0_, (gint) _tmp0__length1, (glong) (*dim).width, option);
		_tmp1_ = photo_metadata_height_tags;
		_tmp1__length1 = photo_metadata_height_tags_length1;
		photo_metadata_set_all_long (self, _tmp1_, (gint) _tmp1__length1, (glong) (*dim).height, option);
	} else {
		gchar** _tmp2_;
		gint _tmp2__length1;
		gchar** _tmp3_;
		gint _tmp3__length1;
		_tmp2_ = photo_metadata_width_tags;
		_tmp2__length1 = photo_metadata_width_tags_length1;
		photo_metadata_remove_tags (self, _tmp2_, (gint) _tmp2__length1);
		_tmp3_ = photo_metadata_height_tags;
		_tmp3__length1 = photo_metadata_height_tags_length1;
		photo_metadata_remove_tags (self, _tmp3_, (gint) _tmp3__length1);
	}
}

static gchar*
string_strip (const gchar* self)
{
	gchar* _result_ = NULL;
	gchar* _tmp0_;
	gchar* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = g_strdup (self);
	_result_ = _tmp0_;
	g_strstrip (_result_);
	result = _result_;
	return result;
}

static gboolean
string_contains (const gchar* self,
                 const gchar* needle)
{
	gchar* _tmp0_;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	g_return_val_if_fail (needle != NULL, FALSE);
	_tmp0_ = strstr ((gchar*) self, (gchar*) needle);
	result = _tmp0_ != NULL;
	return result;
}

static gchar*
photo_metadata_real_get_title (MediaMetadata* base)
{
	PhotoMetadata * self;
	GeeList* _tmp0_ = NULL;
	GeeList* titles = NULL;
	GeeList* _tmp4_;
	gchar* _tmp5_ = NULL;
	gboolean _tmp6_ = FALSE;
	GeeList* _tmp7_;
	gchar* title = NULL;
	gchar* _tmp13_;
	const gchar* _tmp14_;
	const gchar* _tmp17_ = NULL;
	gboolean _tmp18_ = FALSE;
	gboolean _tmp19_ = FALSE;
	const gchar* _tmp20_;
	gchar* _tmp24_;
	gchar* result;
	self = (PhotoMetadata*) base;
	if (photo_metadata_has_tag (self, PHOTO_METADATA_IPHOTO_TITLE_TAG)) {
		GeeList* _tmp1_;
		_tmp1_ = photo_metadata_get_string_multiple (self, PHOTO_METADATA_IPHOTO_TITLE_TAG);
		_g_object_unref0 (_tmp0_);
		_tmp0_ = _tmp1_;
	} else {
		gchar** _tmp2_;
		gint _tmp2__length1;
		GeeList* _tmp3_;
		_tmp2_ = photo_metadata_standard_title_tags;
		_tmp2__length1 = photo_metadata_standard_title_tags_length1;
		_tmp3_ = photo_metadata_get_first_string_multiple (self, _tmp2_, (gint) _tmp2__length1);
		_g_object_unref0 (_tmp0_);
		_tmp0_ = _tmp3_;
	}
	_tmp4_ = _tmp0_;
	_tmp0_ = NULL;
	titles = _tmp4_;
	_tmp7_ = titles;
	if (_tmp7_ != NULL) {
		GeeList* _tmp8_;
		gint _tmp9_;
		gint _tmp10_;
		_tmp8_ = titles;
		_tmp9_ = gee_collection_get_size ((GeeCollection*) _tmp8_);
		_tmp10_ = _tmp9_;
		_tmp6_ = _tmp10_ > 0;
	} else {
		_tmp6_ = FALSE;
	}
	if (_tmp6_) {
		GeeList* _tmp11_;
		gpointer _tmp12_;
		_tmp11_ = titles;
		_tmp12_ = gee_list_get (_tmp11_, 0);
		_g_free0 (_tmp5_);
		_tmp5_ = (gchar*) _tmp12_;
	} else {
		_g_free0 (_tmp5_);
		_tmp5_ = NULL;
	}
	_tmp13_ = _tmp5_;
	_tmp5_ = NULL;
	title = _tmp13_;
	_tmp14_ = title;
	if (_tmp14_ != NULL) {
		const gchar* _tmp15_;
		gchar* _tmp16_;
		_tmp15_ = title;
		_tmp16_ = string_strip (_tmp15_);
		_g_free0 (title);
		title = _tmp16_;
	}
	_tmp20_ = title;
	if (!is_string_empty (_tmp20_)) {
		const gchar* _tmp21_;
		_tmp21_ = title;
		_tmp19_ = !string_contains (_tmp21_, "\n");
	} else {
		_tmp19_ = FALSE;
	}
	if (_tmp19_) {
		const gchar* _tmp22_;
		_tmp22_ = title;
		_tmp18_ = !string_contains (_tmp22_, "\r");
	} else {
		_tmp18_ = FALSE;
	}
	if (_tmp18_) {
		const gchar* _tmp23_;
		_tmp23_ = title;
		_tmp17_ = _tmp23_;
	} else {
		_tmp17_ = NULL;
	}
	_tmp24_ = g_strdup (_tmp17_);
	result = _tmp24_;
	_g_free0 (title);
	_g_free0 (_tmp5_);
	_g_object_unref0 (titles);
	_g_object_unref0 (_tmp0_);
	return result;
}

void
photo_metadata_set_title (PhotoMetadata* self,
                          const gchar* title,
                          PhotoMetadataSetOption option)
{
	g_return_if_fail (self != NULL);
	if (!is_string_empty (title)) {
		if (photo_metadata_has_tag (self, PHOTO_METADATA_IPHOTO_TITLE_TAG)) {
			photo_metadata_set_string (self, PHOTO_METADATA_IPHOTO_TITLE_TAG, title, PHOTO_METADATA_PREPARE_STRING_OPTIONS);
		} else {
			gchar** _tmp0_;
			gint _tmp0__length1;
			_tmp0_ = photo_metadata_standard_title_tags;
			_tmp0__length1 = photo_metadata_standard_title_tags_length1;
			photo_metadata_set_all_string (self, _tmp0_, (gint) _tmp0__length1, title, option);
		}
	} else {
		gchar** _tmp1_;
		gint _tmp1__length1;
		_tmp1_ = photo_metadata_standard_title_tags;
		_tmp1__length1 = photo_metadata_standard_title_tags_length1;
		photo_metadata_remove_tags (self, _tmp1_, (gint) _tmp1__length1);
	}
}

static gchar*
photo_metadata_real_get_comment (MediaMetadata* base)
{
	PhotoMetadata * self;
	gchar* _tmp0_;
	gchar* result;
	self = (PhotoMetadata*) base;
	_tmp0_ = photo_metadata_get_string_interpreted (self, "Exif.Photo.UserComment", PREPARE_INPUT_TEXT_OPTIONS_DEFAULT & (~PREPARE_INPUT_TEXT_OPTIONS_STRIP_CRLF));
	result = _tmp0_;
	return result;
}

void
photo_metadata_set_comment (PhotoMetadata* self,
                            const gchar* comment)
{
	g_return_if_fail (self != NULL);
	if (!is_string_empty (comment)) {
		photo_metadata_set_string (self, "Exif.Photo.UserComment", comment, PREPARE_INPUT_TEXT_OPTIONS_DEFAULT & (~PREPARE_INPUT_TEXT_OPTIONS_STRIP_CRLF));
	} else {
		photo_metadata_remove_tag (self, "Exif.Photo.UserComment");
	}
}

GeeSet*
photo_metadata_get_keywords (PhotoMetadata* self,
                             GCompareDataFunc compare_func,
                             gpointer compare_func_target,
                             GDestroyNotify compare_func_target_destroy_notify)
{
	GeeSet* keywords = NULL;
	gchar** _tmp0_;
	gint _tmp0__length1;
	GeeSet* _tmp21_ = NULL;
	gboolean _tmp22_ = FALSE;
	GeeSet* _tmp23_;
	GeeSet* _tmp28_;
	GeeSet* result;
	g_return_val_if_fail (self != NULL, NULL);
	keywords = NULL;
	_tmp0_ = photo_metadata_keyword_tags;
	_tmp0__length1 = photo_metadata_keyword_tags_length1;
	{
		gchar** tag_collection = NULL;
		gint tag_collection_length1 = 0;
		gint _tag_collection_size_ = 0;
		gint tag_it = 0;
		tag_collection = _tmp0_;
		tag_collection_length1 = _tmp0__length1;
		for (tag_it = 0; tag_it < tag_collection_length1; tag_it = tag_it + 1) {
			gchar* _tmp1_;
			gchar* tag = NULL;
			_tmp1_ = g_strdup (tag_collection[tag_it]);
			tag = _tmp1_;
			{
				GeeCollection* values = NULL;
				const gchar* _tmp2_;
				GeeList* _tmp3_;
				gboolean _tmp4_ = FALSE;
				GeeCollection* _tmp5_;
				_tmp2_ = tag;
				_tmp3_ = photo_metadata_get_string_multiple (self, _tmp2_);
				values = (GeeCollection*) _tmp3_;
				_tmp5_ = values;
				if (_tmp5_ != NULL) {
					GeeCollection* _tmp6_;
					gint _tmp7_;
					gint _tmp8_;
					_tmp6_ = values;
					_tmp7_ = gee_collection_get_size (_tmp6_);
					_tmp8_ = _tmp7_;
					_tmp4_ = _tmp8_ > 0;
				} else {
					_tmp4_ = FALSE;
				}
				if (_tmp4_) {
					GeeSet* _tmp9_;
					_tmp9_ = keywords;
					if (_tmp9_ == NULL) {
						GCompareDataFunc _tmp10_;
						gpointer _tmp10__target;
						GDestroyNotify _tmp10__target_destroy_notify;
						GeeSet* _tmp11_;
						_tmp10_ = compare_func;
						_tmp10__target = compare_func_target;
						_tmp10__target_destroy_notify = compare_func_target_destroy_notify;
						compare_func = NULL;
						compare_func_target = NULL;
						compare_func_target_destroy_notify = NULL;
						_tmp11_ = photo_metadata_create_string_set (self, _tmp10_, _tmp10__target, _tmp10__target_destroy_notify);
						_g_object_unref0 (keywords);
						keywords = _tmp11_;
					}
					{
						GeeIterator* _current_value_it = NULL;
						GeeCollection* _tmp12_;
						GeeIterator* _tmp13_;
						_tmp12_ = values;
						_tmp13_ = gee_iterable_iterator ((GeeIterable*) _tmp12_);
						_current_value_it = _tmp13_;
						while (TRUE) {
							GeeIterator* _tmp14_;
							gchar* current_value = NULL;
							GeeIterator* _tmp15_;
							gpointer _tmp16_;
							GeeSet* _tmp17_;
							const gchar* _tmp18_;
							gchar* _tmp19_;
							gchar* _tmp20_;
							_tmp14_ = _current_value_it;
							if (!gee_iterator_next (_tmp14_)) {
								break;
							}
							_tmp15_ = _current_value_it;
							_tmp16_ = gee_iterator_get (_tmp15_);
							current_value = (gchar*) _tmp16_;
							_tmp17_ = keywords;
							_tmp18_ = current_value;
							_tmp19_ = hierarchical_tag_utilities_make_flat_tag_safe (_tmp18_);
							_tmp20_ = _tmp19_;
							gee_collection_add ((GeeCollection*) _tmp17_, _tmp20_);
							_g_free0 (_tmp20_);
							_g_free0 (current_value);
						}
						_g_object_unref0 (_current_value_it);
					}
				}
				_g_object_unref0 (values);
				_g_free0 (tag);
			}
		}
	}
	_tmp23_ = keywords;
	if (_tmp23_ != NULL) {
		GeeSet* _tmp24_;
		gint _tmp25_;
		gint _tmp26_;
		_tmp24_ = keywords;
		_tmp25_ = gee_collection_get_size ((GeeCollection*) _tmp24_);
		_tmp26_ = _tmp25_;
		_tmp22_ = _tmp26_ > 0;
	} else {
		_tmp22_ = FALSE;
	}
	if (_tmp22_) {
		GeeSet* _tmp27_;
		_tmp27_ = keywords;
		_tmp21_ = _tmp27_;
	} else {
		_tmp21_ = NULL;
	}
	_tmp28_ = _g_object_ref0 (_tmp21_);
	result = _tmp28_;
	_g_object_unref0 (keywords);
	(compare_func_target_destroy_notify == NULL) ? NULL : (compare_func_target_destroy_notify (compare_func_target), NULL);
	compare_func = NULL;
	compare_func_target = NULL;
	compare_func_target_destroy_notify = NULL;
	return result;
}

static gpointer
_hierarchical_keyword_field_ref0 (gpointer self)
{
	return self ? hierarchical_keyword_field_ref (self) : NULL;
}

static gchar*
string_replace (const gchar* self,
                const gchar* old,
                const gchar* replacement)
{
	gboolean _tmp0_ = FALSE;
	gboolean _tmp1_ = FALSE;
	GError* _inner_error0_ = NULL;
	gchar* result;
	g_return_val_if_fail (self != NULL, NULL);
	g_return_val_if_fail (old != NULL, NULL);
	g_return_val_if_fail (replacement != NULL, NULL);
	if ((*((gchar*) self)) == '\0') {
		_tmp1_ = TRUE;
	} else {
		_tmp1_ = (*((gchar*) old)) == '\0';
	}
	if (_tmp1_) {
		_tmp0_ = TRUE;
	} else {
		_tmp0_ = g_strcmp0 (old, replacement) == 0;
	}
	if (_tmp0_) {
		gchar* _tmp2_;
		_tmp2_ = g_strdup (self);
		result = _tmp2_;
		return result;
	}
	{
		GRegex* regex = NULL;
		gchar* _tmp3_;
		gchar* _tmp4_;
		GRegex* _tmp5_;
		GRegex* _tmp6_;
		gchar* _tmp7_ = NULL;
		GRegex* _tmp8_;
		gchar* _tmp9_;
		gchar* _tmp10_;
		_tmp3_ = g_regex_escape_string (old, -1);
		_tmp4_ = _tmp3_;
		_tmp5_ = g_regex_new (_tmp4_, 0, 0, &_inner_error0_);
		_tmp6_ = _tmp5_;
		_g_free0 (_tmp4_);
		regex = _tmp6_;
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			if (_inner_error0_->domain == G_REGEX_ERROR) {
				goto __catch0_g_regex_error;
			}
			g_critical ("file %s: line %d: unexpected error: %s (%s, %d)", __FILE__, __LINE__, _inner_error0_->message, g_quark_to_string (_inner_error0_->domain), _inner_error0_->code);
			g_clear_error (&_inner_error0_);
			return NULL;
		}
		_tmp8_ = regex;
		_tmp9_ = g_regex_replace_literal (_tmp8_, self, (gssize) -1, 0, replacement, 0, &_inner_error0_);
		_tmp7_ = _tmp9_;
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			_g_regex_unref0 (regex);
			if (_inner_error0_->domain == G_REGEX_ERROR) {
				goto __catch0_g_regex_error;
			}
			g_critical ("file %s: line %d: unexpected error: %s (%s, %d)", __FILE__, __LINE__, _inner_error0_->message, g_quark_to_string (_inner_error0_->domain), _inner_error0_->code);
			g_clear_error (&_inner_error0_);
			return NULL;
		}
		_tmp10_ = _tmp7_;
		_tmp7_ = NULL;
		result = _tmp10_;
		_g_free0 (_tmp7_);
		_g_regex_unref0 (regex);
		return result;
	}
	goto __finally0;
	__catch0_g_regex_error:
	{
		g_clear_error (&_inner_error0_);
		g_assert_not_reached ();
	}
	__finally0:
	g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error0_->message, g_quark_to_string (_inner_error0_->domain), _inner_error0_->code);
	g_clear_error (&_inner_error0_);
	return NULL;
}

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

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

static void
photo_metadata_internal_set_hierarchical_keywords (PhotoMetadata* self,
                                                   HierarchicalTagIndex* index)
{
	HierarchicalKeywordField** _tmp0_;
	gint _tmp0__length1;
	HierarchicalKeywordField** _tmp4_;
	gint _tmp4__length1;
	g_return_if_fail (self != NULL);
	_tmp0_ = photo_metadata_hierarchical_keyword_tags;
	_tmp0__length1 = photo_metadata_hierarchical_keyword_tags_length1;
	{
		HierarchicalKeywordField** current_field_collection = NULL;
		gint current_field_collection_length1 = 0;
		gint _current_field_collection_size_ = 0;
		gint current_field_it = 0;
		current_field_collection = _tmp0_;
		current_field_collection_length1 = _tmp0__length1;
		for (current_field_it = 0; current_field_it < current_field_collection_length1; current_field_it = current_field_it + 1) {
			HierarchicalKeywordField* _tmp1_;
			HierarchicalKeywordField* current_field = NULL;
			_tmp1_ = _hierarchical_keyword_field_ref0 (current_field_collection[current_field_it]);
			current_field = _tmp1_;
			{
				HierarchicalKeywordField* _tmp2_;
				const gchar* _tmp3_;
				_tmp2_ = current_field;
				_tmp3_ = _tmp2_->field_name;
				photo_metadata_remove_tag (self, _tmp3_);
				_hierarchical_keyword_field_unref0 (current_field);
			}
		}
	}
	if (index == NULL) {
		return;
	}
	_tmp4_ = photo_metadata_hierarchical_keyword_tags;
	_tmp4__length1 = photo_metadata_hierarchical_keyword_tags_length1;
	{
		HierarchicalKeywordField** current_field_collection = NULL;
		gint current_field_collection_length1 = 0;
		gint _current_field_collection_size_ = 0;
		gint current_field_it = 0;
		current_field_collection = _tmp4_;
		current_field_collection_length1 = _tmp4__length1;
		for (current_field_it = 0; current_field_it < current_field_collection_length1; current_field_it = current_field_it + 1) {
			HierarchicalKeywordField* _tmp5_;
			HierarchicalKeywordField* current_field = NULL;
			_tmp5_ = _hierarchical_keyword_field_ref0 (current_field_collection[current_field_it]);
			current_field = _tmp5_;
			{
				HierarchicalKeywordField* _tmp6_;
				GeeSet* writeable_set = NULL;
				GeeTreeSet* _tmp7_;
				HierarchicalKeywordField* _tmp24_;
				const gchar* _tmp25_;
				GeeSet* _tmp26_;
				_tmp6_ = current_field;
				if (!_tmp6_->is_writeable) {
					_hierarchical_keyword_field_unref0 (current_field);
					continue;
				}
				_tmp7_ = gee_tree_set_new (G_TYPE_STRING, (GBoxedCopyFunc) g_strdup, (GDestroyNotify) g_free, NULL, NULL, NULL);
				writeable_set = (GeeSet*) _tmp7_;
				{
					GeeIterator* _current_path_it = NULL;
					GeeCollection* _tmp8_;
					GeeCollection* _tmp9_;
					GeeIterator* _tmp10_;
					GeeIterator* _tmp11_;
					_tmp8_ = hierarchical_tag_index_get_all_paths (index);
					_tmp9_ = _tmp8_;
					_tmp10_ = gee_iterable_iterator ((GeeIterable*) _tmp9_);
					_tmp11_ = _tmp10_;
					_g_object_unref0 (_tmp9_);
					_current_path_it = _tmp11_;
					while (TRUE) {
						GeeIterator* _tmp12_;
						gchar* current_path = NULL;
						GeeIterator* _tmp13_;
						gpointer _tmp14_;
						gchar* writeable_path = NULL;
						const gchar* _tmp15_;
						HierarchicalKeywordField* _tmp16_;
						const gchar* _tmp17_;
						gchar* _tmp18_;
						HierarchicalKeywordField* _tmp19_;
						GeeSet* _tmp22_;
						const gchar* _tmp23_;
						_tmp12_ = _current_path_it;
						if (!gee_iterator_next (_tmp12_)) {
							break;
						}
						_tmp13_ = _current_path_it;
						_tmp14_ = gee_iterator_get (_tmp13_);
						current_path = (gchar*) _tmp14_;
						_tmp15_ = current_path;
						_tmp16_ = current_field;
						_tmp17_ = _tmp16_->path_separator;
						_tmp18_ = string_replace (_tmp15_, TAG_PATH_SEPARATOR_STRING, _tmp17_);
						writeable_path = _tmp18_;
						_tmp19_ = current_field;
						if (!_tmp19_->wants_leading_separator) {
							const gchar* _tmp20_;
							gchar* _tmp21_;
							_tmp20_ = writeable_path;
							_tmp21_ = string_substring (_tmp20_, (glong) 1, (glong) -1);
							_g_free0 (writeable_path);
							writeable_path = _tmp21_;
						}
						_tmp22_ = writeable_set;
						_tmp23_ = writeable_path;
						gee_collection_add ((GeeCollection*) _tmp22_, _tmp23_);
						_g_free0 (writeable_path);
						_g_free0 (current_path);
					}
					_g_object_unref0 (_current_path_it);
				}
				_tmp24_ = current_field;
				_tmp25_ = _tmp24_->field_name;
				_tmp26_ = writeable_set;
				photo_metadata_set_string_multiple (self, _tmp25_, (GeeCollection*) _tmp26_);
				_g_object_unref0 (writeable_set);
				_hierarchical_keyword_field_unref0 (current_field);
			}
		}
	}
}

void
photo_metadata_set_keywords (PhotoMetadata* self,
                             GeeCollection* keywords,
                             PhotoMetadataSetOption option)
{
	HierarchicalTagIndex* htag_index = NULL;
	HierarchicalTagIndex* _tmp0_;
	GeeSet* flat_keywords = NULL;
	GeeTreeSet* _tmp1_;
	g_return_if_fail (self != NULL);
	_tmp0_ = hierarchical_tag_index_new ();
	htag_index = _tmp0_;
	_tmp1_ = gee_tree_set_new (G_TYPE_STRING, (GBoxedCopyFunc) g_strdup, (GDestroyNotify) g_free, NULL, NULL, NULL);
	flat_keywords = (GeeSet*) _tmp1_;
	if (keywords != NULL) {
		GeeSet* _tmp19_;
		HierarchicalTagIndex* _tmp20_;
		GeeCollection* _tmp21_;
		GeeCollection* _tmp22_;
		{
			GeeIterator* _keyword_it = NULL;
			GeeIterator* _tmp2_;
			_tmp2_ = gee_iterable_iterator ((GeeIterable*) keywords);
			_keyword_it = _tmp2_;
			while (TRUE) {
				GeeIterator* _tmp3_;
				gchar* keyword = NULL;
				GeeIterator* _tmp4_;
				gpointer _tmp5_;
				const gchar* _tmp6_;
				_tmp3_ = _keyword_it;
				if (!gee_iterator_next (_tmp3_)) {
					break;
				}
				_tmp4_ = _keyword_it;
				_tmp5_ = gee_iterator_get (_tmp4_);
				keyword = (gchar*) _tmp5_;
				_tmp6_ = keyword;
				if (g_str_has_prefix (_tmp6_, TAG_PATH_SEPARATOR_STRING)) {
					GeeCollection* path_components = NULL;
					const gchar* _tmp7_;
					GeeList* _tmp8_;
					_tmp7_ = keyword;
					_tmp8_ = hierarchical_tag_utilities_enumerate_path_components (_tmp7_);
					path_components = (GeeCollection*) _tmp8_;
					{
						GeeIterator* _component_it = NULL;
						GeeCollection* _tmp9_;
						GeeIterator* _tmp10_;
						_tmp9_ = path_components;
						_tmp10_ = gee_iterable_iterator ((GeeIterable*) _tmp9_);
						_component_it = _tmp10_;
						while (TRUE) {
							GeeIterator* _tmp11_;
							gchar* component = NULL;
							GeeIterator* _tmp12_;
							gpointer _tmp13_;
							HierarchicalTagIndex* _tmp14_;
							const gchar* _tmp15_;
							const gchar* _tmp16_;
							_tmp11_ = _component_it;
							if (!gee_iterator_next (_tmp11_)) {
								break;
							}
							_tmp12_ = _component_it;
							_tmp13_ = gee_iterator_get (_tmp12_);
							component = (gchar*) _tmp13_;
							_tmp14_ = htag_index;
							_tmp15_ = component;
							_tmp16_ = keyword;
							hierarchical_tag_index_add_path (_tmp14_, _tmp15_, _tmp16_);
							_g_free0 (component);
						}
						_g_object_unref0 (_component_it);
					}
					_g_object_unref0 (path_components);
				} else {
					GeeSet* _tmp17_;
					const gchar* _tmp18_;
					_tmp17_ = flat_keywords;
					_tmp18_ = keyword;
					gee_collection_add ((GeeCollection*) _tmp17_, _tmp18_);
				}
				_g_free0 (keyword);
			}
			_g_object_unref0 (_keyword_it);
		}
		_tmp19_ = flat_keywords;
		_tmp20_ = htag_index;
		_tmp21_ = hierarchical_tag_index_get_all_tags (_tmp20_);
		_tmp22_ = _tmp21_;
		gee_collection_add_all ((GeeCollection*) _tmp19_, _tmp22_);
		_g_object_unref0 (_tmp22_);
	}
	if (keywords != NULL) {
		gchar** _tmp23_;
		gint _tmp23__length1;
		GeeSet* _tmp24_;
		HierarchicalTagIndex* _tmp25_;
		_tmp23_ = photo_metadata_keyword_tags;
		_tmp23__length1 = photo_metadata_keyword_tags_length1;
		_tmp24_ = flat_keywords;
		photo_metadata_set_all_string_multiple (self, _tmp23_, (gint) _tmp23__length1, (GeeCollection*) _tmp24_, option);
		_tmp25_ = htag_index;
		photo_metadata_internal_set_hierarchical_keywords (self, _tmp25_);
	} else {
		gchar** _tmp26_;
		gint _tmp26__length1;
		_tmp26_ = photo_metadata_keyword_tags;
		_tmp26__length1 = photo_metadata_keyword_tags_length1;
		photo_metadata_remove_tags (self, _tmp26_, (gint) _tmp26__length1);
		photo_metadata_internal_set_hierarchical_keywords (self, NULL);
	}
	_g_object_unref0 (flat_keywords);
	_hierarchical_tag_index_unref0 (htag_index);
}

gboolean
photo_metadata_has_hierarchical_keywords (PhotoMetadata* self)
{
	HierarchicalKeywordField** _tmp0_;
	gint _tmp0__length1;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	_tmp0_ = photo_metadata_hierarchical_keyword_tags;
	_tmp0__length1 = photo_metadata_hierarchical_keyword_tags_length1;
	{
		HierarchicalKeywordField** field_collection = NULL;
		gint field_collection_length1 = 0;
		gint _field_collection_size_ = 0;
		gint field_it = 0;
		field_collection = _tmp0_;
		field_collection_length1 = _tmp0__length1;
		for (field_it = 0; field_it < field_collection_length1; field_it = field_it + 1) {
			HierarchicalKeywordField* _tmp1_;
			HierarchicalKeywordField* field = NULL;
			_tmp1_ = _hierarchical_keyword_field_ref0 (field_collection[field_it]);
			field = _tmp1_;
			{
				GeeCollection* values = NULL;
				HierarchicalKeywordField* _tmp2_;
				const gchar* _tmp3_;
				GeeList* _tmp4_;
				gboolean _tmp5_ = FALSE;
				GeeCollection* _tmp6_;
				_tmp2_ = field;
				_tmp3_ = _tmp2_->field_name;
				_tmp4_ = photo_metadata_get_string_multiple (self, _tmp3_);
				values = (GeeCollection*) _tmp4_;
				_tmp6_ = values;
				if (_tmp6_ != NULL) {
					GeeCollection* _tmp7_;
					gint _tmp8_;
					gint _tmp9_;
					_tmp7_ = values;
					_tmp8_ = gee_collection_get_size (_tmp7_);
					_tmp9_ = _tmp8_;
					_tmp5_ = _tmp9_ > 0;
				} else {
					_tmp5_ = FALSE;
				}
				if (_tmp5_) {
					result = TRUE;
					_g_object_unref0 (values);
					_hierarchical_keyword_field_unref0 (field);
					return result;
				}
				_g_object_unref0 (values);
				_hierarchical_keyword_field_unref0 (field);
			}
		}
	}
	result = FALSE;
	return result;
}

GeeSet*
photo_metadata_get_hierarchical_keywords (PhotoMetadata* self)
{
	GeeSet* h_keywords = NULL;
	GeeSet* _tmp0_;
	HierarchicalKeywordField** _tmp1_;
	gint _tmp1__length1;
	GeeSet* result;
	g_return_val_if_fail (self != NULL, NULL);
	_vala_assert (photo_metadata_has_hierarchical_keywords (self), "has_hierarchical_keywords ()");
	_tmp0_ = photo_metadata_create_string_set (self, NULL, NULL, NULL);
	h_keywords = _tmp0_;
	_tmp1_ = photo_metadata_hierarchical_keyword_tags;
	_tmp1__length1 = photo_metadata_hierarchical_keyword_tags_length1;
	{
		HierarchicalKeywordField** field_collection = NULL;
		gint field_collection_length1 = 0;
		gint _field_collection_size_ = 0;
		gint field_it = 0;
		field_collection = _tmp1_;
		field_collection_length1 = _tmp1__length1;
		for (field_it = 0; field_it < field_collection_length1; field_it = field_it + 1) {
			HierarchicalKeywordField* _tmp2_;
			HierarchicalKeywordField* field = NULL;
			_tmp2_ = _hierarchical_keyword_field_ref0 (field_collection[field_it]);
			field = _tmp2_;
			{
				GeeCollection* values = NULL;
				HierarchicalKeywordField* _tmp3_;
				const gchar* _tmp4_;
				GeeList* _tmp5_;
				gboolean _tmp6_ = FALSE;
				GeeCollection* _tmp7_;
				_tmp3_ = field;
				_tmp4_ = _tmp3_->field_name;
				_tmp5_ = photo_metadata_get_string_multiple (self, _tmp4_);
				values = (GeeCollection*) _tmp5_;
				_tmp7_ = values;
				if (_tmp7_ == NULL) {
					_tmp6_ = TRUE;
				} else {
					GeeCollection* _tmp8_;
					gint _tmp9_;
					gint _tmp10_;
					_tmp8_ = values;
					_tmp9_ = gee_collection_get_size (_tmp8_);
					_tmp10_ = _tmp9_;
					_tmp6_ = _tmp10_ < 1;
				}
				if (_tmp6_) {
					_g_object_unref0 (values);
					_hierarchical_keyword_field_unref0 (field);
					continue;
				}
				{
					GeeIterator* _current_value_it = NULL;
					GeeCollection* _tmp11_;
					GeeIterator* _tmp12_;
					_tmp11_ = values;
					_tmp12_ = gee_iterable_iterator ((GeeIterable*) _tmp11_);
					_current_value_it = _tmp12_;
					while (TRUE) {
						GeeIterator* _tmp13_;
						gchar* current_value = NULL;
						GeeIterator* _tmp14_;
						gpointer _tmp15_;
						gchar* canonicalized = NULL;
						const gchar* _tmp16_;
						HierarchicalKeywordField* _tmp17_;
						const gchar* _tmp18_;
						gchar* _tmp19_;
						const gchar* _tmp20_;
						_tmp13_ = _current_value_it;
						if (!gee_iterator_next (_tmp13_)) {
							break;
						}
						_tmp14_ = _current_value_it;
						_tmp15_ = gee_iterator_get (_tmp14_);
						current_value = (gchar*) _tmp15_;
						_tmp16_ = current_value;
						_tmp17_ = field;
						_tmp18_ = _tmp17_->path_separator;
						_tmp19_ = hierarchical_tag_utilities_canonicalize (_tmp16_, _tmp18_);
						canonicalized = _tmp19_;
						_tmp20_ = canonicalized;
						if (_tmp20_ != NULL) {
							GeeSet* _tmp21_;
							const gchar* _tmp22_;
							_tmp21_ = h_keywords;
							_tmp22_ = canonicalized;
							gee_collection_add ((GeeCollection*) _tmp21_, _tmp22_);
						}
						_g_free0 (canonicalized);
						_g_free0 (current_value);
					}
					_g_object_unref0 (_current_value_it);
				}
				_g_object_unref0 (values);
				_hierarchical_keyword_field_unref0 (field);
			}
		}
	}
	result = h_keywords;
	return result;
}

gboolean
photo_metadata_has_orientation (PhotoMetadata* self)
{
	GExiv2Metadata* _tmp0_;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	_tmp0_ = self->priv->exiv2;
	result = gexiv2_metadata_get_orientation (_tmp0_) == GEXIV2_ORIENTATION_UNSPECIFIED;
	return result;
}

Orientation
photo_metadata_get_orientation (PhotoMetadata* self)
{
	GExiv2Orientation orientation = 0;
	GExiv2Metadata* _tmp0_;
	gboolean _tmp1_ = FALSE;
	gboolean _tmp2_ = FALSE;
	Orientation result;
	g_return_val_if_fail (self != NULL, 0);
	_tmp0_ = self->priv->exiv2;
	orientation = gexiv2_metadata_get_orientation (_tmp0_);
	if (orientation == GEXIV2_ORIENTATION_UNSPECIFIED) {
		_tmp2_ = TRUE;
	} else {
		_tmp2_ = orientation < ORIENTATION_MIN;
	}
	if (_tmp2_) {
		_tmp1_ = TRUE;
	} else {
		_tmp1_ = orientation > ORIENTATION_MAX;
	}
	if (_tmp1_) {
		result = ORIENTATION_TOP_LEFT;
		return result;
	} else {
		result = (Orientation) orientation;
		return result;
	}
}

void
photo_metadata_set_orientation (PhotoMetadata* self,
                                Orientation orientation)
{
	GExiv2Metadata* _tmp0_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->exiv2;
	gexiv2_metadata_set_orientation (_tmp0_, (GExiv2Orientation) orientation);
}

gboolean
photo_metadata_get_gps (PhotoMetadata* self,
                        gdouble* longitude,
                        gchar** long_ref,
                        gdouble* latitude,
                        gchar** lat_ref,
                        gdouble* altitude)
{
	gdouble _vala_longitude = 0.0;
	gchar* _vala_long_ref = NULL;
	gdouble _vala_latitude = 0.0;
	gchar* _vala_lat_ref = NULL;
	gdouble _vala_altitude = 0.0;
	GExiv2Metadata* _tmp0_;
	gdouble _tmp1_ = 0.0;
	gdouble _tmp2_ = 0.0;
	gdouble _tmp3_ = 0.0;
	gboolean _tmp4_;
	gchar* _tmp5_;
	gchar* _tmp6_;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	_tmp0_ = self->priv->exiv2;
	_tmp4_ = gexiv2_metadata_get_gps_info (_tmp0_, &_tmp1_, &_tmp2_, &_tmp3_);
	_vala_longitude = _tmp1_;
	_vala_latitude = _tmp2_;
	_vala_altitude = _tmp3_;
	if (!_tmp4_) {
		_g_free0 (_vala_long_ref);
		_vala_long_ref = NULL;
		_g_free0 (_vala_lat_ref);
		_vala_lat_ref = NULL;
		result = FALSE;
		if (longitude) {
			*longitude = _vala_longitude;
		}
		if (long_ref) {
			*long_ref = _vala_long_ref;
		} else {
			_g_free0 (_vala_long_ref);
		}
		if (latitude) {
			*latitude = _vala_latitude;
		}
		if (lat_ref) {
			*lat_ref = _vala_lat_ref;
		} else {
			_g_free0 (_vala_lat_ref);
		}
		if (altitude) {
			*altitude = _vala_altitude;
		}
		return result;
	}
	_tmp5_ = photo_metadata_get_string (self, "Exif.GPSInfo.GPSLongitudeRef", PHOTO_METADATA_PREPARE_STRING_OPTIONS);
	_g_free0 (_vala_long_ref);
	_vala_long_ref = _tmp5_;
	_tmp6_ = photo_metadata_get_string (self, "Exif.GPSInfo.GPSLatitudeRef", PHOTO_METADATA_PREPARE_STRING_OPTIONS);
	_g_free0 (_vala_lat_ref);
	_vala_lat_ref = _tmp6_;
	result = TRUE;
	if (longitude) {
		*longitude = _vala_longitude;
	}
	if (long_ref) {
		*long_ref = _vala_long_ref;
	} else {
		_g_free0 (_vala_long_ref);
	}
	if (latitude) {
		*latitude = _vala_latitude;
	}
	if (lat_ref) {
		*lat_ref = _vala_lat_ref;
	} else {
		_g_free0 (_vala_lat_ref);
	}
	if (altitude) {
		*altitude = _vala_altitude;
	}
	return result;
}

gboolean
photo_metadata_get_exposure (PhotoMetadata* self,
                             MetadataRational* exposure)
{
	MetadataRational _vala_exposure = {0};
	MetadataRational _tmp0_ = {0};
	gboolean _tmp1_;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	_tmp1_ = photo_metadata_get_rational (self, "Exif.Photo.ExposureTime", &_tmp0_);
	_vala_exposure = _tmp0_;
	result = _tmp1_;
	if (exposure) {
		*exposure = _vala_exposure;
	}
	return result;
}

gchar*
photo_metadata_get_exposure_string (PhotoMetadata* self)
{
	MetadataRational exposure_time = {0};
	MetadataRational _tmp0_ = {0};
	gboolean _tmp1_;
	gchar* _tmp2_;
	gchar* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp1_ = photo_metadata_get_rational (self, "Exif.Photo.ExposureTime", &_tmp0_);
	exposure_time = _tmp0_;
	if (!_tmp1_) {
		result = NULL;
		return result;
	}
	if (!metadata_rational_is_valid (&exposure_time)) {
		result = NULL;
		return result;
	}
	_tmp2_ = photo_metadata_get_string_interpreted (self, "Exif.Photo.ExposureTime", PHOTO_METADATA_PREPARE_STRING_OPTIONS);
	result = _tmp2_;
	return result;
}

gboolean
photo_metadata_get_iso (PhotoMetadata* self,
                        glong* iso)
{
	glong _vala_iso = 0L;
	gboolean fetched_ok = FALSE;
	glong _tmp0_ = 0L;
	gboolean _tmp1_;
	gboolean _tmp2_ = FALSE;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	_tmp1_ = photo_metadata_get_long (self, "Exif.Photo.ISOSpeedRatings", &_tmp0_);
	_vala_iso = _tmp0_;
	fetched_ok = _tmp1_;
	if (fetched_ok == FALSE) {
		result = FALSE;
		if (iso) {
			*iso = _vala_iso;
		}
		return result;
	}
	if (_vala_iso < ((glong) 6)) {
		_tmp2_ = TRUE;
	} else {
		_tmp2_ = _vala_iso > ((glong) 409600);
	}
	if (_tmp2_) {
		result = FALSE;
		if (iso) {
			*iso = _vala_iso;
		}
		return result;
	}
	result = TRUE;
	if (iso) {
		*iso = _vala_iso;
	}
	return result;
}

gchar*
photo_metadata_get_iso_string (PhotoMetadata* self)
{
	glong iso = 0L;
	glong _tmp0_ = 0L;
	gboolean _tmp1_;
	gchar* _tmp2_;
	gchar* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp1_ = photo_metadata_get_iso (self, &_tmp0_);
	iso = _tmp0_;
	if (!_tmp1_) {
		result = NULL;
		return result;
	}
	_tmp2_ = photo_metadata_get_string_interpreted (self, "Exif.Photo.ISOSpeedRatings", PHOTO_METADATA_PREPARE_STRING_OPTIONS);
	result = _tmp2_;
	return result;
}

gboolean
photo_metadata_get_aperture (PhotoMetadata* self,
                             MetadataRational* aperture)
{
	MetadataRational _vala_aperture = {0};
	MetadataRational _tmp0_ = {0};
	gboolean _tmp1_;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	_tmp1_ = photo_metadata_get_rational (self, "Exif.Photo.FNumber", &_tmp0_);
	_vala_aperture = _tmp0_;
	result = _tmp1_;
	if (aperture) {
		*aperture = _vala_aperture;
	}
	return result;
}

gchar*
photo_metadata_get_aperture_string (PhotoMetadata* self,
                                    gboolean pango_formatted)
{
	MetadataRational aperture = {0};
	MetadataRational _tmp0_ = {0};
	gboolean _tmp1_;
	gdouble aperture_value = 0.0;
	MetadataRational _tmp2_;
	MetadataRational _tmp3_;
	const gchar* _tmp4_ = NULL;
	const gchar* _tmp5_ = NULL;
	gchar* _tmp6_;
	gchar* _tmp7_;
	gchar* _tmp8_;
	gchar* _tmp9_;
	gchar* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp1_ = photo_metadata_get_aperture (self, &_tmp0_);
	aperture = _tmp0_;
	if (!_tmp1_) {
		result = NULL;
		return result;
	}
	_tmp2_ = aperture;
	_tmp3_ = aperture;
	aperture_value = ((gdouble) _tmp2_.numerator) / ((gdouble) _tmp3_.denominator);
	aperture_value = ((gint) (aperture_value * 10.0)) / 10.0;
	if (pango_formatted) {
		_tmp4_ = "<i>f</i>/";
	} else {
		_tmp4_ = "f/";
	}
	if (fmod (aperture_value, 1) == ((gdouble) 0)) {
		_tmp5_ = "%.0f";
	} else {
		_tmp5_ = "%.1f";
	}
	_tmp6_ = g_strdup_printf (_tmp5_, aperture_value);
	_tmp7_ = _tmp6_;
	_tmp8_ = g_strconcat (_tmp4_, _tmp7_, NULL);
	_tmp9_ = _tmp8_;
	_g_free0 (_tmp7_);
	result = _tmp9_;
	return result;
}

gchar*
photo_metadata_get_camera_make (PhotoMetadata* self)
{
	gchar* _tmp0_;
	gchar* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = photo_metadata_get_string_interpreted (self, "Exif.Image.Make", PHOTO_METADATA_PREPARE_STRING_OPTIONS);
	result = _tmp0_;
	return result;
}

gchar*
photo_metadata_get_camera_model (PhotoMetadata* self)
{
	gchar* _tmp0_;
	gchar* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = photo_metadata_get_string_interpreted (self, "Exif.Image.Model", PHOTO_METADATA_PREPARE_STRING_OPTIONS);
	result = _tmp0_;
	return result;
}

gboolean
photo_metadata_get_flash (PhotoMetadata* self,
                          glong* flash)
{
	glong _vala_flash = 0L;
	glong _tmp0_ = 0L;
	gboolean _tmp1_;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	_tmp1_ = photo_metadata_get_long (self, "Exif.Photo.Flash", &_tmp0_);
	_vala_flash = _tmp0_;
	result = _tmp1_;
	if (flash) {
		*flash = _vala_flash;
	}
	return result;
}

gchar*
photo_metadata_get_flash_string (PhotoMetadata* self)
{
	gchar* _tmp0_;
	gchar* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = photo_metadata_get_string_interpreted (self, "Exif.Photo.Flash", PHOTO_METADATA_PREPARE_STRING_OPTIONS);
	result = _tmp0_;
	return result;
}

gboolean
photo_metadata_get_focal_length (PhotoMetadata* self,
                                 MetadataRational* focal_length)
{
	MetadataRational _vala_focal_length = {0};
	MetadataRational _tmp0_ = {0};
	gboolean _tmp1_;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	_tmp1_ = photo_metadata_get_rational (self, "Exif.Photo.FocalLength", &_tmp0_);
	_vala_focal_length = _tmp0_;
	result = _tmp1_;
	if (focal_length) {
		*focal_length = _vala_focal_length;
	}
	return result;
}

gchar*
photo_metadata_get_focal_length_string (PhotoMetadata* self)
{
	gchar* _tmp0_;
	gchar* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = photo_metadata_get_string_interpreted (self, "Exif.Photo.FocalLength", PHOTO_METADATA_PREPARE_STRING_OPTIONS);
	result = _tmp0_;
	return result;
}

gchar*
photo_metadata_get_artist (PhotoMetadata* self)
{
	gchar** _tmp0_;
	gint _tmp0__length1;
	gchar* _tmp1_;
	gchar* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = photo_metadata_artist_tags;
	_tmp0__length1 = photo_metadata_artist_tags_length1;
	_tmp1_ = photo_metadata_get_first_string_interpreted (self, _tmp0_, (gint) _tmp0__length1);
	result = _tmp1_;
	return result;
}

gchar*
photo_metadata_get_copyright (PhotoMetadata* self)
{
	gchar* _tmp0_;
	gchar* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = photo_metadata_get_string_interpreted (self, "Exif.Image.Copyright", PHOTO_METADATA_PREPARE_STRING_OPTIONS);
	result = _tmp0_;
	return result;
}

gchar*
photo_metadata_get_software (PhotoMetadata* self)
{
	gchar* _tmp0_;
	gchar* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = photo_metadata_get_string_interpreted (self, "Exif.Image.Software", PHOTO_METADATA_PREPARE_STRING_OPTIONS);
	result = _tmp0_;
	return result;
}

void
photo_metadata_set_software (PhotoMetadata* self,
                             const gchar* software,
                             const gchar* version)
{
	gchar* _tmp0_;
	gchar* _tmp1_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (software != NULL);
	g_return_if_fail (version != NULL);
	_tmp0_ = g_strdup_printf ("%s %s", software, version);
	_tmp1_ = _tmp0_;
	photo_metadata_set_string (self, "Exif.Image.Software", _tmp1_, PHOTO_METADATA_PREPARE_STRING_OPTIONS);
	_g_free0 (_tmp1_);
	if (photo_metadata_has_iptc (self)) {
		photo_metadata_set_string (self, "Iptc.Application2.Program", software, PHOTO_METADATA_PREPARE_STRING_OPTIONS);
		photo_metadata_set_string (self, "Iptc.Application2.ProgramVersion", version, PHOTO_METADATA_PREPARE_STRING_OPTIONS);
	}
}

void
photo_metadata_remove_software (PhotoMetadata* self)
{
	g_return_if_fail (self != NULL);
	photo_metadata_remove_tag (self, "Exif.Image.Software");
	photo_metadata_remove_tag (self, "Iptc.Application2.Program");
	photo_metadata_remove_tag (self, "Iptc.Application2.ProgramVersion");
}

gchar*
photo_metadata_get_exposure_bias (PhotoMetadata* self)
{
	gchar* _tmp0_;
	gchar* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = photo_metadata_get_string_interpreted (self, "Exif.Photo.ExposureBiasValue", PHOTO_METADATA_PREPARE_STRING_OPTIONS);
	result = _tmp0_;
	return result;
}

static gpointer
_media_metadata_ref0 (gpointer self)
{
	return self ? media_metadata_ref (self) : NULL;
}

static PhotoMetadataInternalPhotoPreview*
photo_metadata_internal_photo_preview_construct (GType object_type,
                                                 PhotoMetadata* owner,
                                                 const gchar* name,
                                                 guint number,
                                                 GExiv2PreviewProperties* props)
{
	PhotoMetadataInternalPhotoPreview* self = NULL;
	Dimensions _tmp0_ = {0};
	const gchar* _tmp1_;
	const gchar* _tmp2_;
	PhotoMetadata* _tmp3_;
	g_return_val_if_fail (owner != NULL, NULL);
	g_return_val_if_fail (name != NULL, NULL);
	g_return_val_if_fail (props != NULL, NULL);
	dimensions_init (&_tmp0_, (gint) gexiv2_preview_properties_get_width (props), (gint) gexiv2_preview_properties_get_height (props));
	_tmp1_ = gexiv2_preview_properties_get_mime_type (props);
	_tmp2_ = gexiv2_preview_properties_get_extension (props);
	self = (PhotoMetadataInternalPhotoPreview*) photo_preview_construct (object_type, name, &_tmp0_, gexiv2_preview_properties_get_size (props), _tmp1_, _tmp2_);
	_tmp3_ = _media_metadata_ref0 (owner);
	_media_metadata_unref0 (self->owner);
	self->owner = _tmp3_;
	self->number = number;
	return self;
}

static PhotoMetadataInternalPhotoPreview*
photo_metadata_internal_photo_preview_new (PhotoMetadata* owner,
                                           const gchar* name,
                                           guint number,
                                           GExiv2PreviewProperties* props)
{
	return photo_metadata_internal_photo_preview_construct (PHOTO_METADATA_TYPE_INTERNAL_PHOTO_PREVIEW, owner, name, number, props);
}

static GBytes*
photo_metadata_internal_photo_preview_real_flatten (PhotoPreview* base,
                                                    GError** error)
{
	PhotoMetadataInternalPhotoPreview * self;
	GExiv2PreviewProperties** props = NULL;
	PhotoMetadata* _tmp0_;
	GExiv2Metadata* _tmp1_;
	GExiv2PreviewProperties** _tmp2_;
	GExiv2PreviewProperties** _tmp3_;
	gint props_length1;
	gint _props_size_;
	gboolean _tmp4_ = FALSE;
	GExiv2PreviewProperties** _tmp5_;
	gint _tmp5__length1;
	PhotoMetadata* _tmp7_;
	GExiv2Metadata* _tmp8_;
	GExiv2PreviewProperties** _tmp9_;
	gint _tmp9__length1;
	GExiv2PreviewProperties* _tmp10_;
	GExiv2PreviewImage* _tmp11_;
	GExiv2PreviewImage* _tmp12_;
	guint32 _tmp13_ = 0;
	guint8* _tmp14_;
	GBytes* _tmp15_;
	GBytes* _tmp16_;
	GBytes* result;
	self = (PhotoMetadataInternalPhotoPreview*) base;
	_tmp0_ = self->owner;
	_tmp1_ = _tmp0_->priv->exiv2;
	_tmp3_ = _tmp2_ = gexiv2_metadata_get_preview_properties (_tmp1_);
	props = _tmp3_;
	props_length1 = _vala_array_length (_tmp2_);
	_props_size_ = props_length1;
	_tmp5_ = props;
	_tmp5__length1 = props_length1;
	if (_tmp5_ != NULL) {
		GExiv2PreviewProperties** _tmp6_;
		gint _tmp6__length1;
		_tmp6_ = props;
		_tmp6__length1 = props_length1;
		_tmp4_ = ((guint) _tmp6__length1) > self->number;
	} else {
		_tmp4_ = FALSE;
	}
	_vala_assert (_tmp4_, "props != null && props.length > number");
	_tmp7_ = self->owner;
	_tmp8_ = _tmp7_->priv->exiv2;
	_tmp9_ = props;
	_tmp9__length1 = props_length1;
	_tmp10_ = _tmp9_[self->number];
	_tmp11_ = gexiv2_metadata_get_preview_image (_tmp8_, _tmp10_);
	_tmp12_ = _tmp11_;
	_tmp14_ = gexiv2_preview_image_get_data (_tmp12_, &_tmp13_);
	_tmp15_ = g_bytes_new (_tmp14_, _tmp13_);
	_tmp16_ = _tmp15_;
	_g_object_unref0 (_tmp12_);
	result = _tmp16_;
	return result;
}

static void
photo_metadata_internal_photo_preview_class_init (PhotoMetadataInternalPhotoPreviewClass * klass,
                                                  gpointer klass_data)
{
	photo_metadata_internal_photo_preview_parent_class = g_type_class_peek_parent (klass);
	((PhotoPreviewClass *) klass)->finalize = photo_metadata_internal_photo_preview_finalize;
	((PhotoPreviewClass *) klass)->flatten = (GBytes* (*) (PhotoPreview*, GError**)) photo_metadata_internal_photo_preview_real_flatten;
}

static void
photo_metadata_internal_photo_preview_instance_init (PhotoMetadataInternalPhotoPreview * self,
                                                     gpointer klass)
{
}

static void
photo_metadata_internal_photo_preview_finalize (PhotoPreview * obj)
{
	PhotoMetadataInternalPhotoPreview * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, PHOTO_METADATA_TYPE_INTERNAL_PHOTO_PREVIEW, PhotoMetadataInternalPhotoPreview);
	_media_metadata_unref0 (self->owner);
	PHOTO_PREVIEW_CLASS (photo_metadata_internal_photo_preview_parent_class)->finalize (obj);
}

static GType
photo_metadata_internal_photo_preview_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (PhotoMetadataInternalPhotoPreviewClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) photo_metadata_internal_photo_preview_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (PhotoMetadataInternalPhotoPreview), 0, (GInstanceInitFunc) photo_metadata_internal_photo_preview_instance_init, NULL };
	GType photo_metadata_internal_photo_preview_type_id;
	photo_metadata_internal_photo_preview_type_id = g_type_register_static (TYPE_PHOTO_PREVIEW, "PhotoMetadataInternalPhotoPreview", &g_define_type_info, 0);
	return photo_metadata_internal_photo_preview_type_id;
}

static GType
photo_metadata_internal_photo_preview_get_type (void)
{
	static volatile gsize photo_metadata_internal_photo_preview_type_id__once = 0;
	if (g_once_init_enter (&photo_metadata_internal_photo_preview_type_id__once)) {
		GType photo_metadata_internal_photo_preview_type_id;
		photo_metadata_internal_photo_preview_type_id = photo_metadata_internal_photo_preview_get_type_once ();
		g_once_init_leave (&photo_metadata_internal_photo_preview_type_id__once, photo_metadata_internal_photo_preview_type_id);
	}
	return photo_metadata_internal_photo_preview_type_id__once;
}

static void
photo_metadata_class_init (PhotoMetadataClass * klass,
                           gpointer klass_data)
{
	gchar* _tmp0_;
	gchar* _tmp1_;
	gchar* _tmp2_;
	gchar** _tmp3_;
	gchar* _tmp4_;
	gchar* _tmp5_;
	gchar* _tmp6_;
	gchar* _tmp7_;
	gchar* _tmp8_;
	gchar* _tmp9_;
	gchar** _tmp10_;
	gchar* _tmp11_;
	gchar* _tmp12_;
	gchar** _tmp13_;
	gchar* _tmp14_;
	gchar* _tmp15_;
	gchar* _tmp16_;
	gchar* _tmp17_;
	gchar** _tmp18_;
	gchar* _tmp19_;
	gchar* _tmp20_;
	gchar* _tmp21_;
	gchar* _tmp22_;
	gchar** _tmp23_;
	gchar* _tmp24_;
	gchar* _tmp25_;
	gchar* _tmp26_;
	gchar* _tmp27_;
	gchar** _tmp28_;
	gchar* _tmp29_;
	gchar* _tmp30_;
	gchar** _tmp31_;
	HierarchicalKeywordField* _tmp32_;
	HierarchicalKeywordField* _tmp33_;
	HierarchicalKeywordField* _tmp34_;
	HierarchicalKeywordField** _tmp35_;
	gchar* _tmp36_;
	gchar* _tmp37_;
	gchar** _tmp38_;
	photo_metadata_parent_class = g_type_class_peek_parent (klass);
	((MediaMetadataClass *) klass)->finalize = photo_metadata_finalize;
	g_type_class_adjust_private_offset (klass, &PhotoMetadata_private_offset);
	((MediaMetadataClass *) klass)->read_from_file = (void (*) (MediaMetadata*, GFile*, GError**)) photo_metadata_real_read_from_file;
	((MediaMetadataClass *) klass)->get_creation_date_time = (MetadataDateTime* (*) (MediaMetadata*)) photo_metadata_real_get_creation_date_time;
	((MediaMetadataClass *) klass)->get_title = (gchar* (*) (MediaMetadata*)) photo_metadata_real_get_title;
	((MediaMetadataClass *) klass)->get_comment = (gchar* (*) (MediaMetadata*)) photo_metadata_real_get_comment;
	_tmp0_ = g_strdup ("Exif.Image.DateTime");
	_tmp1_ = g_strdup ("Xmp.tiff.DateTime");
	_tmp2_ = g_strdup ("Xmp.xmp.ModifyDate");
	_tmp3_ = g_new0 (gchar*, 3 + 1);
	_tmp3_[0] = _tmp0_;
	_tmp3_[1] = _tmp1_;
	_tmp3_[2] = _tmp2_;
	photo_metadata_date_int64ags = _tmp3_;
	photo_metadata_date_int64ags_length1 = 3;
	_photo_metadata_date_int64ags_size_ = photo_metadata_date_int64ags_length1;
	_tmp4_ = g_strdup ("Exif.Photo.DateTimeOriginal");
	_tmp5_ = g_strdup ("Xmp.exif.DateTimeOriginal");
	_tmp6_ = g_strdup ("Xmp.xmp.CreateDate");
	_tmp7_ = g_strdup ("Exif.Photo.DateTimeDigitized");
	_tmp8_ = g_strdup ("Xmp.exif.DateTimeDigitized");
	_tmp9_ = g_strdup ("Exif.Image.DateTime");
	_tmp10_ = g_new0 (gchar*, 6 + 1);
	_tmp10_[0] = _tmp4_;
	_tmp10_[1] = _tmp5_;
	_tmp10_[2] = _tmp6_;
	_tmp10_[3] = _tmp7_;
	_tmp10_[4] = _tmp8_;
	_tmp10_[5] = _tmp9_;
	photo_metadata_exposure_date_int64ags = _tmp10_;
	photo_metadata_exposure_date_int64ags_length1 = 6;
	_photo_metadata_exposure_date_int64ags_size_ = photo_metadata_exposure_date_int64ags_length1;
	_tmp11_ = g_strdup ("Exif.Photo.DateTimeDigitized");
	_tmp12_ = g_strdup ("Xmp.exif.DateTimeDigitized");
	_tmp13_ = g_new0 (gchar*, 2 + 1);
	_tmp13_[0] = _tmp11_;
	_tmp13_[1] = _tmp12_;
	photo_metadata_digitized_date_int64ags = _tmp13_;
	photo_metadata_digitized_date_int64ags_length1 = 2;
	_photo_metadata_digitized_date_int64ags_size_ = photo_metadata_digitized_date_int64ags_length1;
	_tmp14_ = g_strdup ("Exif.Photo.PixelXDimension");
	_tmp15_ = g_strdup ("Xmp.exif.PixelXDimension");
	_tmp16_ = g_strdup ("Xmp.tiff.ImageWidth");
	_tmp17_ = g_strdup ("Xmp.exif.PixelXDimension");
	_tmp18_ = g_new0 (gchar*, 4 + 1);
	_tmp18_[0] = _tmp14_;
	_tmp18_[1] = _tmp15_;
	_tmp18_[2] = _tmp16_;
	_tmp18_[3] = _tmp17_;
	photo_metadata_width_tags = _tmp18_;
	photo_metadata_width_tags_length1 = 4;
	_photo_metadata_width_tags_size_ = photo_metadata_width_tags_length1;
	_tmp19_ = g_strdup ("Exif.Photo.PixelYDimension");
	_tmp20_ = g_strdup ("Xmp.exif.PixelYDimension");
	_tmp21_ = g_strdup ("Xmp.tiff.ImageHeight");
	_tmp22_ = g_strdup ("Xmp.exif.PixelYDimension");
	_tmp23_ = g_new0 (gchar*, 4 + 1);
	_tmp23_[0] = _tmp19_;
	_tmp23_[1] = _tmp20_;
	_tmp23_[2] = _tmp21_;
	_tmp23_[3] = _tmp22_;
	photo_metadata_height_tags = _tmp23_;
	photo_metadata_height_tags_length1 = 4;
	_tmp24_ = g_strdup ("Iptc.Application2.Caption");
	_tmp25_ = g_strdup ("Xmp.dc.title");
	_tmp26_ = g_strdup ("Iptc.Application2.Headline");
	_tmp27_ = g_strdup ("Xmp.photoshop.Headline");
	_tmp28_ = g_new0 (gchar*, 4 + 1);
	_tmp28_[0] = _tmp24_;
	_tmp28_[1] = _tmp25_;
	_tmp28_[2] = _tmp26_;
	_tmp28_[3] = _tmp27_;
	photo_metadata_standard_title_tags = _tmp28_;
	photo_metadata_standard_title_tags_length1 = 4;
	_photo_metadata_standard_title_tags_size_ = photo_metadata_standard_title_tags_length1;
	_tmp29_ = g_strdup ("Xmp.dc.subject");
	_tmp30_ = g_strdup ("Iptc.Application2.Keywords");
	_tmp31_ = g_new0 (gchar*, 2 + 1);
	_tmp31_[0] = _tmp29_;
	_tmp31_[1] = _tmp30_;
	photo_metadata_keyword_tags = _tmp31_;
	photo_metadata_keyword_tags_length1 = 2;
	_photo_metadata_keyword_tags_size_ = photo_metadata_keyword_tags_length1;
	_tmp32_ = hierarchical_keyword_field_new ("Xmp.lr.hierarchicalSubject", "|", FALSE, TRUE);
	_tmp33_ = hierarchical_keyword_field_new ("Xmp.digiKam.TagsList", "/", FALSE, TRUE);
	_tmp34_ = hierarchical_keyword_field_new ("Xmp.MicrosoftPhoto.LastKeywordXMP", "/", FALSE, TRUE);
	_tmp35_ = g_new0 (HierarchicalKeywordField*, 3 + 1);
	_tmp35_[0] = _tmp32_;
	_tmp35_[1] = _tmp33_;
	_tmp35_[2] = _tmp34_;
	photo_metadata_hierarchical_keyword_tags = _tmp35_;
	photo_metadata_hierarchical_keyword_tags_length1 = 3;
	_photo_metadata_hierarchical_keyword_tags_size_ = photo_metadata_hierarchical_keyword_tags_length1;
	_tmp36_ = g_strdup ("Exif.Image.Artist");
	_tmp37_ = g_strdup ("Exif.Canon.OwnerName");
	_tmp38_ = g_new0 (gchar*, 2 + 1);
	_tmp38_[0] = _tmp36_;
	_tmp38_[1] = _tmp37_;
	photo_metadata_artist_tags = _tmp38_;
	photo_metadata_artist_tags_length1 = 2;
	_photo_metadata_artist_tags_size_ = photo_metadata_artist_tags_length1;
}

static void
photo_metadata_instance_init (PhotoMetadata * self,
                              gpointer klass)
{
	GExiv2Metadata* _tmp0_;
	gchar* _tmp1_;
	self->priv = photo_metadata_get_instance_private (self);
	_tmp0_ = gexiv2_metadata_new ();
	self->priv->exiv2 = _tmp0_;
	self->priv->exif = NULL;
	_tmp1_ = g_strdup ("<uninitialized>");
	self->priv->source_name = _tmp1_;
}

static void
photo_metadata_finalize (MediaMetadata * obj)
{
	PhotoMetadata * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, TYPE_PHOTO_METADATA, PhotoMetadata);
	_g_object_unref0 (self->priv->exiv2);
	_exif_data_unref0 (self->priv->exif);
	_g_free0 (self->priv->source_name);
	MEDIA_METADATA_CLASS (photo_metadata_parent_class)->finalize (obj);
}

static GType
photo_metadata_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (PhotoMetadataClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) photo_metadata_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (PhotoMetadata), 0, (GInstanceInitFunc) photo_metadata_instance_init, NULL };
	GType photo_metadata_type_id;
	photo_metadata_type_id = g_type_register_static (TYPE_MEDIA_METADATA, "PhotoMetadata", &g_define_type_info, 0);
	PhotoMetadata_private_offset = g_type_add_instance_private (photo_metadata_type_id, sizeof (PhotoMetadataPrivate));
	return photo_metadata_type_id;
}

GType
photo_metadata_get_type (void)
{
	static volatile gsize photo_metadata_type_id__once = 0;
	if (g_once_init_enter (&photo_metadata_type_id__once)) {
		GType photo_metadata_type_id;
		photo_metadata_type_id = photo_metadata_get_type_once ();
		g_once_init_leave (&photo_metadata_type_id__once, photo_metadata_type_id);
	}
	return photo_metadata_type_id__once;
}

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

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

static gssize
_vala_array_length (gpointer array)
{
	gssize length;
	length = 0;
	if (array) {
		while (((gpointer*) array)[length]) {
			length++;
		}
	}
	return length;
}

static inline gpointer
_vala_memdup2 (gconstpointer mem,
               gsize byte_size)
{
	gpointer new_mem;
	if (mem && byte_size != 0) {
		new_mem = g_malloc (byte_size);
		memcpy (new_mem, mem, byte_size);
	} else {
		new_mem = NULL;
	}
	return new_mem;
}

