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

/*
 * Copyright (c) 2025 focus-timer contributors
 *
 * SPDX-License-Identifier: GPL-3.0-or-later
 *
 * Authors: Kamil Prusko <kamilprusko@gmail.com>
 */

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

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

typedef struct _FtStatsManager FtStatsManager;
typedef struct _FtStatsManagerClass FtStatsManagerClass;
typedef struct _FtStatsManagerPrivate FtStatsManagerPrivate;

#define FT_STATS_MANAGER_TYPE_ITEM (ft_stats_manager_item_get_type ())
typedef struct _FtStatsManagerItem FtStatsManagerItem;

#define FT_STATS_MANAGER_TYPE_SEGMENT (ft_stats_manager_segment_get_type ())
typedef struct _FtStatsManagerSegment FtStatsManagerSegment;
enum  {
	FT_STATS_MANAGER_0_PROPERTY,
	FT_STATS_MANAGER_SESSION_MANAGER_PROPERTY,
	FT_STATS_MANAGER_NUM_PROPERTIES
};
static GParamSpec* ft_stats_manager_properties[FT_STATS_MANAGER_NUM_PROPERTIES];
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
#define _ft_async_queue_unref0(var) ((var == NULL) ? NULL : (var = (ft_async_queue_unref (var), NULL)))
#define _g_free0(var) (var = (g_free (var), NULL))
#define _g_time_zone_unref0(var) ((var == NULL) ? NULL : (var = (g_time_zone_unref (var), NULL)))
typedef struct _Block53Data Block53Data;
#define _g_date_time_unref0(var) ((var == NULL) ? NULL : (var = (g_date_time_unref (var), NULL)))
#define _g_error_free0(var) ((var == NULL) ? NULL : (var = (g_error_free (var), NULL)))
typedef struct _FtStatsManagerFetchEntriesData FtStatsManagerFetchEntriesData;
typedef struct _FtStatsManagerProcessItemData FtStatsManagerProcessItemData;
#define _ft_stats_manager_item_free0(var) ((var == NULL) ? NULL : (var = (ft_stats_manager_item_free (var), NULL)))
typedef struct _FtStatsManagerProcessQueueData FtStatsManagerProcessQueueData;
typedef struct _Block54Data Block54Data;
typedef struct _FtStatsManagerFlushData FtStatsManagerFlushData;
enum  {
	FT_STATS_MANAGER_ENTRY_SAVED_SIGNAL,
	FT_STATS_MANAGER_ENTRY_DELETED_SIGNAL,
	FT_STATS_MANAGER_NUM_SIGNALS
};
static guint ft_stats_manager_signals[FT_STATS_MANAGER_NUM_SIGNALS] = {0};
#define _vala_assert(expr, msg) if G_LIKELY (expr) ; else g_assertion_message_expr (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, msg);
#define _vala_return_if_fail(expr, msg) if G_LIKELY (expr) ; else { g_return_if_fail_warning (G_LOG_DOMAIN, G_STRFUNC, msg); return; }
#define _vala_return_val_if_fail(expr, msg, val) if G_LIKELY (expr) ; else { g_return_if_fail_warning (G_LOG_DOMAIN, G_STRFUNC, msg); return val; }
#define _vala_warn_if_fail(expr, msg) if G_LIKELY (expr) ; else g_warn_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, msg);

struct _FtStatsManager {
	GObject parent_instance;
	FtStatsManagerPrivate * priv;
};

struct _FtStatsManagerClass {
	GObjectClass parent_class;
};

struct _FtStatsManagerSegment {
	gint64 timestamp;
	gint64 duration;
	GDateTime* datetime;
};

struct _FtStatsManagerItem {
	gchar* category;
	gint64 source_id;
	FtStatsManagerSegment* segments;
	gint segments_length1;
	gint _segments_size_;
};

struct _FtStatsManagerPrivate {
	FtSessionManager* _session_manager;
	FtTimezoneHistory* timezone_history;
	FtAsyncQueue* queue;
	gboolean is_processing;
	FtAsyncCallback** flush_callbacks;
	gint flush_callbacks_length1;
	gint _flush_callbacks_size_;
};

struct _Block53Data {
	int _ref_count_;
	FtStatsManager* self;
	FtStatsManagerSegment* segments;
	gint segments_length1;
	gint _segments_size_;
};

struct _FtStatsManagerFetchEntriesData {
	int _state_;
	GObject* _source_object_;
	GAsyncResult* _res_;
	GTask* _async_result;
	FtStatsManager* self;
	GomRepository* repository;
	gchar* category;
	gint64 timestamp;
	gint64 source_id;
	GomResourceGroup* result;
	GomFilter* filter;
	GValue category_value;
	GValue _tmp0_;
	GomFilter* category_filter;
	GValue _tmp1_;
	GomFilter* _tmp2_;
	GValue source_id_value;
	GValue _tmp3_;
	GomFilter* source_id_filter;
	GValue _tmp4_;
	GomFilter* _tmp5_;
	GomFilter* _tmp6_;
	GomFilter* _tmp7_;
	GomFilter* _tmp8_;
	GValue time_value;
	GValue _tmp9_;
	GomFilter* time_filter;
	GValue _tmp10_;
	GomFilter* _tmp11_;
	GomFilter* _tmp12_;
	GomFilter* _tmp13_;
	GomFilter* _tmp14_;
	GomResourceGroup* _tmp15_;
	GomFilter* _tmp16_;
	GomResourceGroup* _tmp17_;
	GomResourceGroup* _tmp18_;
	GError* _inner_error0_;
};

struct _FtStatsManagerProcessItemData {
	int _state_;
	GObject* _source_object_;
	GAsyncResult* _res_;
	GTask* _async_result;
	FtStatsManager* self;
	FtStatsManagerItem item;
	gchar* category;
	FtStatsManagerItem _tmp0_;
	const gchar* _tmp1_;
	gchar* _tmp2_;
	gint64 source_id;
	FtStatsManagerItem _tmp3_;
	FtStatsManagerSegment* segments;
	FtStatsManagerItem _tmp4_;
	FtStatsManagerSegment* _tmp5_;
	gint _tmp5__length1;
	FtStatsManagerSegment* _tmp6_;
	gint _tmp6__length1;
	gint segments_length1;
	gint _segments_size_;
	GomRepository* repository;
	GomRepository* _tmp7_;
	GomRepository* _tmp8_;
	GomResourceGroup* entries;
	GomRepository* _tmp9_;
	const gchar* _tmp10_;
	FtStatsManagerSegment* _tmp11_;
	gint _tmp11__length1;
	FtStatsManagerSegment _tmp12_;
	GomResourceGroup* _tmp13_;
	gint entry_index;
	GomResourceGroup* to_save;
	GomRepository* _tmp14_;
	GObject* _tmp15_;
	GObject* _tmp16_;
	gint to_save_count;
	GomResourceGroup* to_delete;
	GomRepository* _tmp17_;
	GObject* _tmp18_;
	GObject* _tmp19_;
	gint to_delete_count;
	FtStatsEntry** saved_entries;
	FtStatsEntry** _tmp20_;
	gint saved_entries_length1;
	gint _saved_entries_size_;
	FtStatsEntry** deleted_entries;
	FtStatsEntry** _tmp21_;
	gint deleted_entries_length1;
	gint _deleted_entries_size_;
	GomResourceGroup* _tmp22_;
	guint _tmp23_;
	guint _tmp24_;
	GomResourceGroup* _tmp25_;
	GomResourceGroup* _tmp26_;
	guint _tmp27_;
	guint _tmp28_;
	FtStatsManagerSegment* _tmp29_;
	gint _tmp29__length1;
	FtStatsManagerSegment* segment_collection;
	gint segment_collection_length1;
	gint _segment_collection_size_;
	gint segment_it;
	FtStatsManagerSegment _tmp30_;
	FtStatsManagerSegment _tmp31_;
	FtStatsManagerSegment segment;
	FtStatsEntry* entry;
	GDate date;
	gint64 offset;
	GomResourceGroup* _tmp32_;
	guint _tmp33_;
	guint _tmp34_;
	GomResourceGroup* _tmp35_;
	GomResource* _tmp36_;
	FtStatsEntry* _tmp37_;
	gint _tmp38_;
	gboolean _tmp39_;
	FtStatsEntry* _tmp40_;
	gint64 _tmp41_;
	gint64 _tmp42_;
	FtStatsManagerSegment _tmp43_;
	FtStatsEntry* _tmp44_;
	gint64 _tmp45_;
	gint64 _tmp46_;
	FtStatsManagerSegment _tmp47_;
	FtStatsEntry* _tmp48_;
	FtStatsEntry* _tmp49_;
	FtStatsEntry* _tmp50_;
	FtStatsEntry* _tmp51_;
	GomRepository* _tmp52_;
	FtStatsManagerSegment _tmp53_;
	GDateTime* _tmp54_;
	GDate _tmp55_;
	gint64 _tmp56_;
	FtStatsEntry* _tmp57_;
	const gchar* _tmp58_;
	FtStatsEntry* _tmp59_;
	FtStatsManagerSegment _tmp60_;
	FtStatsEntry* _tmp61_;
	GDate _tmp62_;
	gchar* _tmp63_;
	gchar* _tmp64_;
	FtStatsEntry* _tmp65_;
	FtStatsEntry* _tmp66_;
	FtStatsManagerSegment _tmp67_;
	FtStatsEntry* _tmp68_;
	GomResourceGroup* _tmp69_;
	FtStatsEntry* _tmp70_;
	gint _tmp71_;
	FtStatsEntry* _tmp72_;
	FtStatsEntry* _tmp73_;
	GomResourceGroup* _tmp74_;
	GomResourceGroup* _tmp75_;
	guint _tmp76_;
	guint _tmp77_;
	FtStatsEntry* _vala1_entry;
	GomResourceGroup* _tmp78_;
	GomResource* _tmp79_;
	FtStatsEntry* _tmp80_;
	gint _tmp81_;
	FtStatsEntry* _tmp82_;
	FtStatsEntry* _tmp83_;
	FtStatsEntry* _tmp84_;
	GomResourceGroup* _tmp85_;
	FtStatsEntry* _tmp86_;
	gint _tmp87_;
	GomResourceGroup* _tmp88_;
	GomResourceGroup* _tmp89_;
	FtStatsEntry** _tmp90_;
	gint _tmp90__length1;
	FtStatsEntry** entry_collection;
	gint entry_collection_length1;
	gint _entry_collection_size_;
	gint entry_it;
	FtStatsEntry* _tmp91_;
	FtStatsEntry* _vala2_entry;
	FtStatsEntry* _tmp92_;
	FtStatsEntry** _tmp93_;
	gint _tmp93__length1;
	FtStatsEntry** _vala1_entry_collection;
	gint _vala1_entry_collection_length1;
	gint __vala1_entry_collection_size_;
	gint _vala1_entry_it;
	FtStatsEntry* _tmp94_;
	FtStatsEntry* _vala3_entry;
	FtStatsEntry* _tmp95_;
	GError* _inner_error0_;
};

struct _FtStatsManagerProcessQueueData {
	int _state_;
	GObject* _source_object_;
	GAsyncResult* _res_;
	GTask* _async_result;
	FtStatsManager* self;
	FtStatsManagerItem* item;
	FtAsyncQueue* _tmp0_;
	gpointer _tmp1_;
	FtStatsManagerItem* _tmp2_;
	FtStatsManagerItem* _tmp3_;
	FtStatsManagerItem _tmp4_;
	GError* _error_;
	GError* _tmp5_;
	const gchar* _tmp6_;
	FtAsyncCallback** _tmp7_;
	gint _tmp7__length1;
	FtAsyncCallback** callback_collection;
	gint callback_collection_length1;
	gint _callback_collection_size_;
	gint callback_it;
	FtAsyncCallback* callback;
	FtAsyncCallback* _tmp8_;
	GSourceFunc _tmp9_;
	gpointer _tmp9__target;
	FtAsyncCallback** _tmp10_;
	GError* _inner_error0_;
};

struct _Block54Data {
	int _ref_count_;
	FtStatsManager* self;
	gint64 timestamp;
	FtStatsManagerSegment* segments;
	gint segments_length1;
	gint _segments_size_;
};

struct _FtStatsManagerFlushData {
	int _state_;
	GObject* _source_object_;
	GAsyncResult* _res_;
	GTask* _async_result;
	FtStatsManager* self;
	FtAsyncQueue* _tmp0_;
	FtAsyncCallback* _tmp1_;
};

static gint FtStatsManager_private_offset;
static gpointer ft_stats_manager_parent_class = NULL;

static GType ft_stats_manager_item_get_type (void) G_GNUC_CONST  G_GNUC_UNUSED ;
static GType ft_stats_manager_segment_get_type (void) G_GNUC_CONST  G_GNUC_UNUSED ;
static FtStatsManagerSegment* ft_stats_manager_segment_dup (const FtStatsManagerSegment* self);
static void ft_stats_manager_segment_free (FtStatsManagerSegment* self);
static void ft_stats_manager_segment_copy (const FtStatsManagerSegment* self,
                                    FtStatsManagerSegment* dest);
static void ft_stats_manager_segment_destroy (FtStatsManagerSegment* self);
static FtStatsManagerItem* ft_stats_manager_item_dup (const FtStatsManagerItem* self);
static void ft_stats_manager_item_free (FtStatsManagerItem* self);
static void ft_stats_manager_item_copy (const FtStatsManagerItem* self,
                                 FtStatsManagerItem* dest);
static void ft_stats_manager_item_destroy (FtStatsManagerItem* self);
static GDateTime* ft_stats_manager_transform_timestamp (FtStatsManager* self,
                                                 gint64 timestamp);
static void ft_stats_manager_transform_datetime (FtStatsManager* self,
                                          GDateTime* datetime,
                                          GDate* date,
                                          gint64* offset);
static gchar* ft_stats_manager_transform_state (FtStatsManager* self,
                                         FtState state);
static FtStatsManagerSegment* ft_stats_manager_split (FtStatsManager* self,
                                               gint64 timestamp,
                                               gint64 duration,
                                               gint* result_length1);
static Block53Data* block53_data_ref (Block53Data* _data53_);
static void _vala_FtStatsManagerSegment_array_free (FtStatsManagerSegment * array,
                                             gssize array_length);
static void block53_data_unref (void * _userdata_);
static FtStatsManagerSegment* _vala_array_dup18 (FtStatsManagerSegment* self,
                                          gssize length);
static void __lambda96_ (Block53Data* _data53_,
                  gint64 start_time,
                  gint64 end_time,
                  GTimeZone* timezone);
static void _vala_array_add27 (FtStatsManagerSegment* * array,
                        gint* length,
                        gint* size,
                        const FtStatsManagerSegment* value);
static void _vala_array_add28 (FtStatsManagerSegment* * array,
                        gint* length,
                        gint* size,
                        const FtStatsManagerSegment* value);
static void ___lambda96__ft_timezone_scan_func (gint64 start_time,
                                         gint64 end_time,
                                         GTimeZone* timezone,
                                         gpointer self);
static FtStatsManagerSegment* _vala_array_dup19 (FtStatsManagerSegment* self,
                                          gssize length);
static void ft_stats_manager_try_save_time_block (FtStatsManager* self,
                                           FtTimeBlock* time_block);
VALA_EXTERN gboolean ft_is_test (void);
VALA_EXTERN FtSessionEntry* ft_session_create_or_update_entry (FtSession* self);
static gboolean* _bool_dup (gboolean* self);
VALA_EXTERN FtTimeBlockEntry* ft_time_block_create_or_update_entry (FtTimeBlock* self);
static void __lambda97_ (FtStatsManager* self,
                  FtGap* gap);
VALA_EXTERN FtGapEntry* ft_gap_create_or_update_entry (FtGap* self);
static void ___lambda97__gfunc (gconstpointer data,
                         gpointer self);
static void ft_stats_manager_fetch_entries_data_free (gpointer _data);
static void ft_stats_manager_fetch_entries (FtStatsManager* self,
                                     GomRepository* repository,
                                     const gchar* category,
                                     gint64 timestamp,
                                     gint64 source_id,
                                     GAsyncReadyCallback _callback_,
                                     gpointer _user_data_);
static GomResourceGroup* ft_stats_manager_fetch_entries_finish (FtStatsManager* self,
                                                         GAsyncResult* _res_,
                                                         GError** error);
static gboolean ft_stats_manager_fetch_entries_co (FtStatsManagerFetchEntriesData* _data_);
static void ft_stats_manager_fetch_entries_ready (GObject* source_object,
                                           GAsyncResult* _res_,
                                           gpointer _user_data_);
static void ft_stats_manager_process_item_data_free (gpointer _data);
static void ft_stats_manager_process_item (FtStatsManager* self,
                                    FtStatsManagerItem* item,
                                    GAsyncReadyCallback _callback_,
                                    gpointer _user_data_);
static void ft_stats_manager_process_item_finish (FtStatsManager* self,
                                           GAsyncResult* _res_,
                                           GError** error);
static gboolean ft_stats_manager_process_item_co (FtStatsManagerProcessItemData* _data_);
static FtStatsManagerSegment* _vala_array_dup20 (FtStatsManagerSegment* self,
                                          gssize length);
static void ft_stats_manager_process_item_ready (GObject* source_object,
                                          GAsyncResult* _res_,
                                          gpointer _user_data_);
static inline gboolean ft_stats_manager_segment_is_valid (FtStatsManagerSegment *self);
static void _vala_array_add29 (FtStatsEntry** * array,
                        gint* length,
                        gint* size,
                        FtStatsEntry* value);
static void _vala_array_add30 (FtStatsEntry** * array,
                        gint* length,
                        gint* size,
                        FtStatsEntry* value);
static void _vala_array_add31 (FtStatsEntry** * array,
                        gint* length,
                        gint* size,
                        FtStatsEntry* value);
static void ft_stats_manager_process_queue_data_free (gpointer _data);
static void ft_stats_manager_process_queue (FtStatsManager* self,
                                     GAsyncReadyCallback _callback_,
                                     gpointer _user_data_);
static void ft_stats_manager_process_queue_finish (FtStatsManager* self,
                                            GAsyncResult* _res_);
static gboolean ft_stats_manager_process_queue_co (FtStatsManagerProcessQueueData* _data_);
static void ft_stats_manager_process_queue_ready (GObject* source_object,
                                           GAsyncResult* _res_,
                                           gpointer _user_data_);
static void ft_stats_manager_track_internal (FtStatsManager* self,
                                      const gchar* category,
                                      gint64 source_id,
                                      FtStatsManagerSegment* segments,
                                      gint segments_length1);
static FtStatsManagerSegment* _vala_array_dup21 (FtStatsManagerSegment* self,
                                          gssize length);
static FtStatsManagerSegment* _vala_array_dup22 (FtStatsManagerSegment* self,
                                          gssize length);
static FtStatsManagerSegment* ft_stats_manager_intersect_segments (FtStatsManager* self,
                                                            FtStatsManagerSegment* a,
                                                            gint a_length1,
                                                            FtStatsManagerSegment* b,
                                                            gint b_length1,
                                                            gint* result_length1);
static void _vala_array_add32 (FtStatsManagerSegment* * array,
                        gint* length,
                        gint* size,
                        const FtStatsManagerSegment* value);
static Block54Data* block54_data_ref (Block54Data* _data54_);
static void block54_data_unref (void * _userdata_);
static void __lambda98_ (Block54Data* _data54_,
                  FtGap* gap);
static void _vala_array_add33 (FtStatsManagerSegment* * array,
                        gint* length,
                        gint* size,
                        const FtStatsManagerSegment* value);
static void ___lambda98__gfunc (gconstpointer data,
                         gpointer self);
static void _vala_array_add34 (FtStatsManagerSegment* * array,
                        gint* length,
                        gint* size,
                        const FtStatsManagerSegment* value);
static FtStatsManagerSegment* _vala_array_dup23 (FtStatsManagerSegment* self,
                                          gssize length);
static FtStatsManagerSegment* _vala_array_dup24 (FtStatsManagerSegment* self,
                                          gssize length);
static void ft_stats_manager_flush_data_free (gpointer _data);
static gboolean ft_stats_manager_flush_co (FtStatsManagerFlushData* _data_);
static void ft_stats_manager_flush_ready (GObject* source_object,
                                   GAsyncResult* _res_,
                                   gpointer _user_data_);
static gboolean _ft_stats_manager_flush_co_gsource_func (gpointer self);
static void _vala_array_add35 (FtAsyncCallback** * array,
                        gint* length,
                        gint* size,
                        FtAsyncCallback* value);
static void ft_stats_manager_on_time_block_saved (FtStatsManager* self,
                                           FtTimeBlock* time_block,
                                           FtTimeBlockEntry* time_block_entry);
static void ft_stats_manager_on_gap_saved (FtStatsManager* self,
                                    FtGap* gap,
                                    FtGapEntry* gap_entry);
static void ft_stats_manager_real_dispose (GObject* base);
static void _ft_stats_manager_on_time_block_saved_ft_session_manager_time_block_saved (FtSessionManager* _sender,
                                                                                FtTimeBlock* time_block,
                                                                                FtTimeBlockEntry* time_block_entry,
                                                                                gpointer self);
static void _ft_stats_manager_on_gap_saved_ft_session_manager_gap_saved (FtSessionManager* _sender,
                                                                  FtGap* gap,
                                                                  FtGapEntry* gap_entry,
                                                                  gpointer self);
static FtStatsManagerSegment* _vala_array_dup25 (FtStatsManagerSegment* self,
                                          gssize length);
static GObject * ft_stats_manager_constructor (GType type,
                                        guint n_construct_properties,
                                        GObjectConstructParam * construct_properties);
static void ft_stats_manager_finalize (GObject * obj);
static GType ft_stats_manager_get_type_once (void);
static void _vala_ft_stats_manager_get_property (GObject * object,
                                          guint property_id,
                                          GValue * value,
                                          GParamSpec * pspec);
static void _vala_ft_stats_manager_set_property (GObject * object,
                                          guint property_id,
                                          const GValue * value,
                                          GParamSpec * pspec);
static void _vala_array_destroy (gpointer array,
                          gssize array_length,
                          GDestroyNotify destroy_func);
static void _vala_array_free (gpointer array,
                       gssize array_length,
                       GDestroyNotify destroy_func);
static inline gpointer _vala_memdup2 (gconstpointer mem,
                        gsize byte_size);

static inline gpointer
ft_stats_manager_get_instance_private (FtStatsManager* self)
{
	return G_STRUCT_MEMBER_P (self, FtStatsManager_private_offset);
}

FtStatsManager*
ft_stats_manager_construct (GType object_type)
{
	FtStatsManager * self = NULL;
	FtSessionManager* _tmp0_;
	_tmp0_ = ft_session_manager_get_default ();
	self = (FtStatsManager*) g_object_new (object_type, "session-manager", _tmp0_, NULL);
	return self;
}

FtStatsManager*
ft_stats_manager_new (void)
{
	return ft_stats_manager_construct (FT_TYPE_STATS_MANAGER);
}

static gpointer
_g_time_zone_ref0 (gpointer self)
{
	return self ? g_time_zone_ref (self) : NULL;
}

static GDateTime*
ft_stats_manager_transform_timestamp (FtStatsManager* self,
                                      gint64 timestamp)
{
	GTimeZone* timezone = NULL;
	FtTimezoneHistory* _tmp0_;
	GTimeZone* _tmp1_;
	GTimeZone* _tmp2_;
	GTimeZone* _tmp3_;
	GTimeZone* _tmp6_;
	GDateTime* _tmp7_;
	GDateTime* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->timezone_history;
	_tmp1_ = ft_timezone_history_search (_tmp0_, timestamp);
	_tmp2_ = _g_time_zone_ref0 (_tmp1_);
	timezone = _tmp2_;
	_tmp3_ = timezone;
	if (_tmp3_ == NULL) {
		gchar* _tmp4_;
		gchar* _tmp5_;
		_tmp4_ = g_strdup_printf ("%" G_GINT64_FORMAT, timestamp);
		_tmp5_ = _tmp4_;
		g_warning ("stats-manager.vala:79: Did not find timezone for timestamp %s", _tmp5_);
		_g_free0 (_tmp5_);
	}
	_tmp6_ = timezone;
	_tmp7_ = ft_timestamp_to_datetime (timestamp, _tmp6_);
	result = _tmp7_;
	_g_time_zone_unref0 (timezone);
	return result;
}

static void
ft_stats_manager_transform_datetime (FtStatsManager* self,
                                     GDateTime* datetime,
                                     GDate* date,
                                     gint64* offset)
{
	GDate _vala_date = {0};
	gint64 _vala_offset = 0LL;
	g_return_if_fail (self != NULL);
	g_return_if_fail (datetime != NULL);
	memset (&_vala_date, 0, sizeof (GDate));
	g_date_set_dmy (&_vala_date, (GDateDay) g_date_time_get_day_of_month (datetime), (gint) ((GDateMonth) g_date_time_get_month (datetime)), (GDateYear) g_date_time_get_year (datetime));
	_vala_offset = (((g_date_time_get_hour (datetime) * FT_INTERVAL_HOUR) + (g_date_time_get_minute (datetime) * FT_INTERVAL_MINUTE)) + (g_date_time_get_second (datetime) * FT_INTERVAL_SECOND)) + g_date_time_get_microsecond (datetime);
	if (_vala_offset < FT_STATS_MANAGER_MIDNIGHT_OFFSET) {
		g_date_subtract_days (&_vala_date, 1U);
		_vala_offset = _vala_offset + (24 * FT_INTERVAL_HOUR);
	}
	if (date) {
		*date = _vala_date;
	}
	if (offset) {
		*offset = _vala_offset;
	}
}

static gchar*
ft_stats_manager_transform_state (FtStatsManager* self,
                                  FtState state)
{
	gchar* result;
	g_return_val_if_fail (self != NULL, NULL);
	switch (state) {
		case FT_STATE_POMODORO:
		{
			gchar* _tmp0_;
			_tmp0_ = g_strdup ("pomodoro");
			result = _tmp0_;
			return result;
		}
		case FT_STATE_BREAK:
		case FT_STATE_SHORT_BREAK:
		case FT_STATE_LONG_BREAK:
		{
			gchar* _tmp1_;
			_tmp1_ = g_strdup ("break");
			result = _tmp1_;
			return result;
		}
		default:
		{
			result = NULL;
			return result;
		}
	}
}

/**
         * Find timestamps where an entry should be divided: midnights, time-zone changes, etc.
         * `timestamp` is returned as the first split.
         */
static Block53Data*
block53_data_ref (Block53Data* _data53_)
{
	g_atomic_int_inc (&_data53_->_ref_count_);
	return _data53_;
}

static void
_vala_FtStatsManagerSegment_array_free (FtStatsManagerSegment * array,
                                        gssize array_length)
{
	if (array != NULL) {
		gssize i;
		for (i = 0; i < array_length; i = i + 1) {
			ft_stats_manager_segment_destroy (&array[i]);
		}
	}
	g_free (array);
}

static void
block53_data_unref (void * _userdata_)
{
	Block53Data* _data53_;
	_data53_ = (Block53Data*) _userdata_;
	if (g_atomic_int_dec_and_test (&_data53_->_ref_count_)) {
		FtStatsManager* self;
		self = _data53_->self;
		_data53_->segments = (_vala_FtStatsManagerSegment_array_free (_data53_->segments, _data53_->segments_length1), NULL);
		_g_object_unref0 (self);
		g_slice_free (Block53Data, _data53_);
	}
}

static FtStatsManagerSegment*
_vala_array_dup18 (FtStatsManagerSegment* self,
                   gssize length)
{
	if (length > 0) {
		FtStatsManagerSegment* result;
		gssize i;
		result = g_new0 (FtStatsManagerSegment, length);
		for (i = 0; i < length; i++) {
			FtStatsManagerSegment _tmp0_;
			FtStatsManagerSegment _tmp1_ = {0};
			_tmp0_ = self[i];
			ft_stats_manager_segment_copy (&_tmp0_, &_tmp1_);
			result[i] = _tmp1_;
		}
		return result;
	}
	return NULL;
}

static gpointer
_g_date_time_ref0 (gpointer self)
{
	return self ? g_date_time_ref (self) : NULL;
}

static void
_vala_array_add27 (FtStatsManagerSegment* * array,
                   gint* length,
                   gint* size,
                   const FtStatsManagerSegment* value)
{
	if ((*length) == (*size)) {
		*size = (*size) ? (2 * (*size)) : 4;
		*array = g_renew (FtStatsManagerSegment, *array, *size);
	}
	(*array)[(*length)++] = *value;
}

static void
_vala_array_add28 (FtStatsManagerSegment* * array,
                   gint* length,
                   gint* size,
                   const FtStatsManagerSegment* value)
{
	if ((*length) == (*size)) {
		*size = (*size) ? (2 * (*size)) : 4;
		*array = g_renew (FtStatsManagerSegment, *array, *size);
	}
	(*array)[(*length)++] = *value;
}

static void
__lambda96_ (Block53Data* _data53_,
             gint64 start_time,
             gint64 end_time,
             GTimeZone* timezone)
{
	FtStatsManager* self;
	GDateTime* datetime = NULL;
	GDateTime* _tmp0_;
	GDateTime* _tmp1_;
	GDateTime* _tmp4_;
	GDateTime* _tmp5_;
	FtStatsManagerSegment _tmp6_ = {0};
	GDateTime* midnight = NULL;
	GDateTime* _tmp7_;
	GDateTime* _tmp8_;
	GDateTime* _tmp9_;
	GDateTime* _tmp10_;
	GDateTime* _tmp11_;
	GDateTime* _tmp12_;
	self = _data53_->self;
	g_return_if_fail (timezone != NULL);
	_tmp0_ = ft_stats_manager_transform_timestamp (self, start_time);
	datetime = _tmp0_;
	_tmp1_ = datetime;
	if (_tmp1_ == NULL) {
		gchar* _tmp2_;
		gchar* _tmp3_;
		_tmp2_ = g_strdup_printf ("%" G_GINT64_FORMAT, start_time);
		_tmp3_ = _tmp2_;
		g_warning ("stats-manager.vala:143: Failed to convert timestamp %s", _tmp3_);
		_g_free0 (_tmp3_);
		_g_date_time_unref0 (datetime);
		return;
	}
	_tmp4_ = datetime;
	_tmp5_ = _g_date_time_ref0 (_tmp4_);
	memset (&_tmp6_, 0, sizeof (FtStatsManagerSegment));
	_tmp6_.timestamp = start_time;
	_tmp6_.duration = (gint64) 0;
	_g_date_time_unref0 (_tmp6_.datetime);
	_tmp6_.datetime = _tmp5_;
	_vala_array_add27 (&_data53_->segments, &_data53_->segments_length1, &_data53_->_segments_size_, &_tmp6_);
	_tmp7_ = datetime;
	_tmp8_ = datetime;
	_tmp9_ = datetime;
	_tmp10_ = g_date_time_new (timezone, g_date_time_get_year (_tmp7_), g_date_time_get_month (_tmp8_), g_date_time_get_day_of_month (_tmp9_), 0, 0, (gdouble) 0);
	midnight = _tmp10_;
	_tmp11_ = midnight;
	_tmp12_ = g_date_time_add_seconds (_tmp11_, ft_timestamp_to_seconds (FT_STATS_MANAGER_MIDNIGHT_OFFSET));
	_g_date_time_unref0 (midnight);
	midnight = _tmp12_;
	while (TRUE) {
		gint64 midnight_timestamp = 0LL;
		GDateTime* _tmp13_;
		GDateTime* _tmp16_;
		GDateTime* _tmp17_;
		FtStatsManagerSegment _tmp18_ = {0};
		GDateTime* _tmp19_;
		GDateTime* _tmp20_;
		_tmp13_ = midnight;
		midnight_timestamp = ft_timestamp_from_datetime (_tmp13_);
		if (midnight_timestamp > end_time) {
			break;
		}
		if (midnight_timestamp < start_time) {
			GDateTime* _tmp14_;
			GDateTime* _tmp15_;
			_tmp14_ = midnight;
			_tmp15_ = g_date_time_add_days (_tmp14_, 1);
			_g_date_time_unref0 (midnight);
			midnight = _tmp15_;
			continue;
		}
		_tmp16_ = midnight;
		_tmp17_ = _g_date_time_ref0 (_tmp16_);
		memset (&_tmp18_, 0, sizeof (FtStatsManagerSegment));
		_tmp18_.timestamp = midnight_timestamp;
		_tmp18_.duration = (gint64) 0;
		_g_date_time_unref0 (_tmp18_.datetime);
		_tmp18_.datetime = _tmp17_;
		_vala_array_add28 (&_data53_->segments, &_data53_->segments_length1, &_data53_->_segments_size_, &_tmp18_);
		_tmp19_ = midnight;
		_tmp20_ = g_date_time_add_days (_tmp19_, 1);
		_g_date_time_unref0 (midnight);
		midnight = _tmp20_;
	}
	_g_date_time_unref0 (midnight);
	_g_date_time_unref0 (datetime);
}

static void
___lambda96__ft_timezone_scan_func (gint64 start_time,
                                    gint64 end_time,
                                    GTimeZone* timezone,
                                    gpointer self)
{
	__lambda96_ (self, start_time, end_time, timezone);
}

static FtStatsManagerSegment*
_vala_array_dup19 (FtStatsManagerSegment* self,
                   gssize length)
{
	if (length > 0) {
		FtStatsManagerSegment* result;
		gssize i;
		result = g_new0 (FtStatsManagerSegment, length);
		for (i = 0; i < length; i++) {
			FtStatsManagerSegment _tmp0_;
			FtStatsManagerSegment _tmp1_ = {0};
			_tmp0_ = self[i];
			ft_stats_manager_segment_copy (&_tmp0_, &_tmp1_);
			result[i] = _tmp1_;
		}
		return result;
	}
	return NULL;
}

static FtStatsManagerSegment*
ft_stats_manager_split (FtStatsManager* self,
                        gint64 timestamp,
                        gint64 duration,
                        gint* result_length1)
{
	Block53Data* _data53_;
	FtStatsManagerSegment* _tmp0_;
	gboolean _tmp1_ = FALSE;
	FtTimezoneHistory* _tmp5_;
	FtStatsManagerSegment* _tmp14_;
	gint _tmp14__length1;
	FtStatsManagerSegment* _tmp20_;
	gint _tmp20__length1;
	FtStatsManagerSegment* _tmp21_;
	gint _tmp21__length1;
	FtStatsManagerSegment* _tmp22_;
	gint _tmp22__length1;
	FtStatsManagerSegment* result;
	g_return_val_if_fail (self != NULL, NULL);
	_data53_ = g_slice_new0 (Block53Data);
	_data53_->_ref_count_ = 1;
	_data53_->self = g_object_ref (self);
	_tmp0_ = g_new0 (FtStatsManagerSegment, 0);
	_data53_->segments = _tmp0_;
	_data53_->segments_length1 = 0;
	_data53_->_segments_size_ = _data53_->segments_length1;
	if (ft_timestamp_is_undefined (timestamp)) {
		_tmp1_ = TRUE;
	} else {
		_tmp1_ = duration <= ((gint64) 0);
	}
	if (_tmp1_) {
		FtStatsManagerSegment* _tmp2_;
		gint _tmp2__length1;
		FtStatsManagerSegment* _tmp3_;
		gint _tmp3__length1;
		FtStatsManagerSegment* _tmp4_;
		gint _tmp4__length1;
		_tmp2_ = _data53_->segments;
		_tmp2__length1 = _data53_->segments_length1;
		_tmp3_ = (_tmp2_ != NULL) ? _vala_array_dup18 (_tmp2_, _tmp2__length1) : _tmp2_;
		_tmp3__length1 = _tmp2__length1;
		_tmp4_ = _tmp3_;
		_tmp4__length1 = _tmp3__length1;
		if (result_length1) {
			*result_length1 = _tmp4__length1;
		}
		result = _tmp4_;
		block53_data_unref (_data53_);
		_data53_ = NULL;
		return result;
	}
	_tmp5_ = self->priv->timezone_history;
	ft_timezone_history_scan (_tmp5_, timestamp, timestamp + duration, ___lambda96__ft_timezone_scan_func, _data53_);
	{
		gint index = 0;
		index = 0;
		{
			gboolean _tmp6_ = FALSE;
			_tmp6_ = TRUE;
			while (TRUE) {
				FtStatsManagerSegment* _tmp8_;
				gint _tmp8__length1;
				FtStatsManagerSegment* _tmp9_;
				gint _tmp9__length1;
				FtStatsManagerSegment* _tmp10_;
				gint _tmp10__length1;
				FtStatsManagerSegment _tmp11_;
				FtStatsManagerSegment* _tmp12_;
				gint _tmp12__length1;
				FtStatsManagerSegment _tmp13_;
				if (!_tmp6_) {
					gint _tmp7_;
					_tmp7_ = index;
					index = _tmp7_ + 1;
				}
				_tmp6_ = FALSE;
				_tmp8_ = _data53_->segments;
				_tmp8__length1 = _data53_->segments_length1;
				if (!(index < (_tmp8__length1 - 1))) {
					break;
				}
				_tmp9_ = _data53_->segments;
				_tmp9__length1 = _data53_->segments_length1;
				_tmp10_ = _data53_->segments;
				_tmp10__length1 = _data53_->segments_length1;
				_tmp11_ = _tmp10_[index + 1];
				_tmp12_ = _data53_->segments;
				_tmp12__length1 = _data53_->segments_length1;
				_tmp13_ = _tmp12_[index];
				_tmp9_[index].duration = _tmp11_.timestamp - _tmp13_.timestamp;
			}
		}
	}
	_tmp14_ = _data53_->segments;
	_tmp14__length1 = _data53_->segments_length1;
	if (_tmp14__length1 > 0) {
		FtStatsManagerSegment* _tmp15_;
		gint _tmp15__length1;
		FtStatsManagerSegment* _tmp16_;
		gint _tmp16__length1;
		FtStatsManagerSegment* _tmp17_;
		gint _tmp17__length1;
		FtStatsManagerSegment* _tmp18_;
		gint _tmp18__length1;
		FtStatsManagerSegment _tmp19_;
		_tmp15_ = _data53_->segments;
		_tmp15__length1 = _data53_->segments_length1;
		_tmp16_ = _data53_->segments;
		_tmp16__length1 = _data53_->segments_length1;
		_tmp17_ = _data53_->segments;
		_tmp17__length1 = _data53_->segments_length1;
		_tmp18_ = _data53_->segments;
		_tmp18__length1 = _data53_->segments_length1;
		_tmp19_ = _tmp17_[_tmp18__length1 - 1];
		_tmp15_[_tmp16__length1 - 1].duration = (timestamp + duration) - _tmp19_.timestamp;
	}
	_tmp20_ = _data53_->segments;
	_tmp20__length1 = _data53_->segments_length1;
	_tmp21_ = (_tmp20_ != NULL) ? _vala_array_dup19 (_tmp20_, _tmp20__length1) : _tmp20_;
	_tmp21__length1 = _tmp20__length1;
	_tmp22_ = _tmp21_;
	_tmp22__length1 = _tmp21__length1;
	if (result_length1) {
		*result_length1 = _tmp22__length1;
	}
	result = _tmp22_;
	block53_data_unref (_data53_);
	_data53_ = NULL;
	return result;
}

/**
         * Convenience method to ensure entries are saved in database.
         *
         * It's intended for testing `StatsManager` alone. If a `SessionManager` is used,
         * the session manager is responsible for saving time-block/gap entries.
         */
static gpointer
_g_object_ref0 (gpointer self)
{
	return self ? g_object_ref (self) : NULL;
}

static gboolean*
_bool_dup (gboolean* self)
{
	gboolean* dup;
	dup = g_new0 (gboolean, 1);
	memcpy (dup, self, sizeof (gboolean));
	return dup;
}

static gpointer
__bool_dup0 (gpointer self)
{
	return self ? _bool_dup (self) : NULL;
}

static void
__lambda97_ (FtStatsManager* self,
             FtGap* gap)
{
	FtGapEntry* gap_entry = NULL;
	FtGapEntry* _tmp0_;
	FtGapEntry* _tmp1_;
	FtGapEntry* _tmp2_;
	GError* _inner_error0_ = NULL;
	g_return_if_fail (gap != NULL);
	_tmp0_ = ft_gap_create_or_update_entry (gap);
	_tmp1_ = _g_object_ref0 (_tmp0_);
	gap_entry = _tmp1_;
	_tmp2_ = gap_entry;
	if (_tmp2_ != NULL) {
		{
			FtGapEntry* _tmp3_;
			_tmp3_ = gap_entry;
			gom_resource_save_sync ((GomResource*) _tmp3_, &_inner_error0_);
			if (G_UNLIKELY (_inner_error0_ != NULL)) {
				goto __catch0_g_error;
			}
		}
		goto __finally0;
		__catch0_g_error:
		{
			GError* _error_ = NULL;
			GError* _tmp4_;
			const gchar* _tmp5_;
			_error_ = _inner_error0_;
			_inner_error0_ = NULL;
			_tmp4_ = _error_;
			_tmp5_ = _tmp4_->message;
			g_critical ("stats-manager.vala:236: Error saving gap: %s", _tmp5_);
			_g_error_free0 (_error_);
		}
		__finally0:
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			_g_object_unref0 (gap_entry);
			g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error0_->message, g_quark_to_string (_inner_error0_->domain), _inner_error0_->code);
			g_clear_error (&_inner_error0_);
			return;
		}
	}
	_g_object_unref0 (gap_entry);
}

static void
___lambda97__gfunc (gconstpointer data,
                    gpointer self)
{
	__lambda97_ ((FtStatsManager*) self, (FtGap*) data);
}

static void
ft_stats_manager_try_save_time_block (FtStatsManager* self,
                                      FtTimeBlock* time_block)
{
	gboolean _tmp0_ = FALSE;
	FtSessionManager* _tmp3_;
	FtSession* _tmp4_;
	FtSession* _tmp5_;
	GError* _inner_error0_ = NULL;
	g_return_if_fail (self != NULL);
	g_return_if_fail (time_block != NULL);
	if (!ft_is_test ()) {
		_tmp0_ = TRUE;
	} else {
		FtSession* _tmp1_;
		FtSession* _tmp2_;
		_tmp1_ = ft_time_block_get_session (time_block);
		_tmp2_ = _tmp1_;
		_tmp0_ = _tmp2_ == NULL;
	}
	if (_tmp0_) {
		return;
	}
	_tmp3_ = self->priv->_session_manager;
	_tmp4_ = ft_session_manager_get_current_session (_tmp3_);
	_tmp5_ = _tmp4_;
	if (_tmp5_ != NULL) {
		return;
	}
	{
		FtSessionEntry* session_entry = NULL;
		FtSession* _tmp6_;
		FtSession* _tmp7_;
		FtSessionEntry* _tmp8_;
		FtSessionEntry* _tmp9_;
		FtSessionEntry* _tmp10_ = NULL;
		FtSessionEntry* _tmp11_;
		gboolean* _tmp12_ = NULL;
		FtTimeBlockEntry* time_block_entry = NULL;
		FtTimeBlockEntry* _tmp15_;
		FtTimeBlockEntry* _tmp16_;
		FtTimeBlockEntry* _tmp17_ = NULL;
		FtTimeBlockEntry* _tmp18_;
		gboolean* _tmp19_ = NULL;
		_tmp6_ = ft_time_block_get_session (time_block);
		_tmp7_ = _tmp6_;
		_tmp8_ = ft_session_create_or_update_entry (_tmp7_);
		_tmp9_ = _g_object_ref0 (_tmp8_);
		session_entry = _tmp9_;
		_tmp11_ = session_entry;
		_tmp10_ = _tmp11_;
		_tmp12_ = NULL;
		if (_tmp10_ != NULL) {
			gboolean _tmp13_ = FALSE;
			gboolean* _tmp14_;
			_tmp13_ = gom_resource_save_sync ((GomResource*) _tmp10_, &_inner_error0_);
			if (G_UNLIKELY (_inner_error0_ != NULL)) {
				_g_free0 (_tmp12_);
				_g_object_unref0 (session_entry);
				goto __catch0_g_error;
			}
			_tmp14_ = __bool_dup0 (&_tmp13_);
			_g_free0 (_tmp12_);
			_tmp12_ = _tmp14_;
		}
		_tmp15_ = ft_time_block_create_or_update_entry (time_block);
		_tmp16_ = _g_object_ref0 (_tmp15_);
		time_block_entry = _tmp16_;
		_tmp18_ = time_block_entry;
		_tmp17_ = _tmp18_;
		_tmp19_ = NULL;
		if (_tmp17_ != NULL) {
			gboolean _tmp20_ = FALSE;
			gboolean* _tmp21_;
			_tmp20_ = gom_resource_save_sync ((GomResource*) _tmp17_, &_inner_error0_);
			if (G_UNLIKELY (_inner_error0_ != NULL)) {
				_g_free0 (_tmp19_);
				_g_object_unref0 (time_block_entry);
				_g_free0 (_tmp12_);
				_g_object_unref0 (session_entry);
				goto __catch0_g_error;
			}
			_tmp21_ = __bool_dup0 (&_tmp20_);
			_g_free0 (_tmp19_);
			_tmp19_ = _tmp21_;
		}
		_g_free0 (_tmp19_);
		_g_object_unref0 (time_block_entry);
		_g_free0 (_tmp12_);
		_g_object_unref0 (session_entry);
	}
	goto __finally0;
	__catch0_g_error:
	{
		GError* _error_ = NULL;
		GError* _tmp22_;
		const gchar* _tmp23_;
		_error_ = _inner_error0_;
		_inner_error0_ = NULL;
		_tmp22_ = _error_;
		_tmp23_ = _tmp22_->message;
		g_critical ("stats-manager.vala:223: Error saving time-block: %s", _tmp23_);
		_g_error_free0 (_error_);
	}
	__finally0:
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error0_->message, g_quark_to_string (_inner_error0_->domain), _inner_error0_->code);
		g_clear_error (&_inner_error0_);
		return;
	}
	ft_time_block_foreach_gap (time_block, ___lambda97__gfunc, self);
}

static void
ft_stats_manager_fetch_entries_data_free (gpointer _data)
{
	FtStatsManagerFetchEntriesData* _data_;
	_data_ = _data;
	_g_object_unref0 (_data_->repository);
	_g_free0 (_data_->category);
	_g_object_unref0 (_data_->result);
	_g_object_unref0 (_data_->self);
	g_slice_free (FtStatsManagerFetchEntriesData, _data_);
}

static void
ft_stats_manager_fetch_entries (FtStatsManager* self,
                                GomRepository* repository,
                                const gchar* category,
                                gint64 timestamp,
                                gint64 source_id,
                                GAsyncReadyCallback _callback_,
                                gpointer _user_data_)
{
	FtStatsManagerFetchEntriesData* _data_;
	FtStatsManager* _tmp0_;
	GomRepository* _tmp1_;
	gchar* _tmp2_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (repository != NULL);
	g_return_if_fail (category != NULL);
	_data_ = g_slice_new0 (FtStatsManagerFetchEntriesData);
	_data_->_async_result = g_task_new (G_OBJECT (self), NULL, _callback_, _user_data_);
	g_task_set_task_data (_data_->_async_result, _data_, ft_stats_manager_fetch_entries_data_free);
	_tmp0_ = _g_object_ref0 (self);
	_data_->self = _tmp0_;
	_tmp1_ = _g_object_ref0 (repository);
	_g_object_unref0 (_data_->repository);
	_data_->repository = _tmp1_;
	_tmp2_ = g_strdup (category);
	_g_free0 (_data_->category);
	_data_->category = _tmp2_;
	_data_->timestamp = timestamp;
	_data_->source_id = source_id;
	ft_stats_manager_fetch_entries_co (_data_);
}

static GomResourceGroup*
ft_stats_manager_fetch_entries_finish (FtStatsManager* self,
                                       GAsyncResult* _res_,
                                       GError** error)
{
	GomResourceGroup* result;
	FtStatsManagerFetchEntriesData* _data_;
	_data_ = g_task_propagate_pointer (G_TASK (_res_), error);
	if (NULL == _data_) {
		return NULL;
	}
	result = _data_->result;
	_data_->result = NULL;
	return result;
}

static void
ft_stats_manager_fetch_entries_ready (GObject* source_object,
                                      GAsyncResult* _res_,
                                      gpointer _user_data_)
{
	FtStatsManagerFetchEntriesData* _data_;
	_data_ = _user_data_;
	_data_->_source_object_ = source_object;
	_data_->_res_ = _res_;
	ft_stats_manager_fetch_entries_co (_data_);
}

static gboolean
ft_stats_manager_fetch_entries_co (FtStatsManagerFetchEntriesData* _data_)
{
	switch (_data_->_state_) {
		case 0:
		goto _state_0;
		case 1:
		goto _state_1;
		default:
		g_assert_not_reached ();
	}
	_state_0:
	memset (&_data_->_tmp0_, 0, sizeof (GValue));
	g_value_init (&_data_->_tmp0_, G_TYPE_STRING);
	_data_->category_value = _data_->_tmp0_;
	g_value_set_string (&_data_->category_value, _data_->category);
	_data_->_tmp1_ = _data_->category_value;
	_data_->_tmp2_ = gom_filter_new_eq (FT_TYPE_STATS_ENTRY, "category", &_data_->_tmp1_);
	g_object_ref_sink (_data_->_tmp2_);
	_data_->category_filter = _data_->_tmp2_;
	if (_data_->source_id != ((gint64) 0)) {
		memset (&_data_->_tmp3_, 0, sizeof (GValue));
		g_value_init (&_data_->_tmp3_, G_TYPE_INT64);
		_data_->source_id_value = _data_->_tmp3_;
		g_value_set_int64 (&_data_->source_id_value, _data_->source_id);
		_data_->_tmp4_ = _data_->source_id_value;
		_data_->_tmp5_ = gom_filter_new_eq (FT_TYPE_STATS_ENTRY, "source-id", &_data_->_tmp4_);
		g_object_ref_sink (_data_->_tmp5_);
		_data_->source_id_filter = _data_->_tmp5_;
		_data_->_tmp6_ = _data_->category_filter;
		_data_->_tmp7_ = _data_->source_id_filter;
		_data_->_tmp8_ = gom_filter_new_and (_data_->_tmp6_, _data_->_tmp7_);
		g_object_ref_sink (_data_->_tmp8_);
		_g_object_unref0 (_data_->filter);
		_data_->filter = _data_->_tmp8_;
		_g_object_unref0 (_data_->source_id_filter);
		G_IS_VALUE (&_data_->source_id_value) ? (g_value_unset (&_data_->source_id_value), NULL) : NULL;
	} else {
		memset (&_data_->_tmp9_, 0, sizeof (GValue));
		g_value_init (&_data_->_tmp9_, G_TYPE_INT64);
		_data_->time_value = _data_->_tmp9_;
		g_value_set_int64 (&_data_->time_value, _data_->timestamp);
		_data_->_tmp10_ = _data_->time_value;
		_data_->_tmp11_ = gom_filter_new_eq (FT_TYPE_STATS_ENTRY, "time", &_data_->_tmp10_);
		g_object_ref_sink (_data_->_tmp11_);
		_data_->time_filter = _data_->_tmp11_;
		_data_->_tmp12_ = _data_->category_filter;
		_data_->_tmp13_ = _data_->time_filter;
		_data_->_tmp14_ = gom_filter_new_and (_data_->_tmp12_, _data_->_tmp13_);
		g_object_ref_sink (_data_->_tmp14_);
		_g_object_unref0 (_data_->filter);
		_data_->filter = _data_->_tmp14_;
		_g_object_unref0 (_data_->time_filter);
		G_IS_VALUE (&_data_->time_value) ? (g_value_unset (&_data_->time_value), NULL) : NULL;
	}
	_data_->_tmp16_ = _data_->filter;
	_data_->_state_ = 1;
	gom_repository_find_async (_data_->repository, FT_TYPE_STATS_ENTRY, _data_->_tmp16_, ft_stats_manager_fetch_entries_ready, _data_);
	return FALSE;
	_state_1:
	_data_->_tmp17_ = gom_repository_find_finish (_data_->repository, _data_->_res_, &_data_->_inner_error0_);
	_data_->_tmp15_ = _data_->_tmp17_;
	if (G_UNLIKELY (_data_->_inner_error0_ != NULL)) {
		g_task_return_error (_data_->_async_result, _data_->_inner_error0_);
		_g_object_unref0 (_data_->category_filter);
		G_IS_VALUE (&_data_->category_value) ? (g_value_unset (&_data_->category_value), NULL) : NULL;
		_g_object_unref0 (_data_->filter);
		g_object_unref (_data_->_async_result);
		return FALSE;
	}
	_data_->_tmp18_ = _data_->_tmp15_;
	_data_->_tmp15_ = NULL;
	_data_->result = _data_->_tmp18_;
	_g_object_unref0 (_data_->_tmp15_);
	_g_object_unref0 (_data_->category_filter);
	G_IS_VALUE (&_data_->category_value) ? (g_value_unset (&_data_->category_value), NULL) : NULL;
	_g_object_unref0 (_data_->filter);
	g_task_return_pointer (_data_->_async_result, _data_, NULL);
	if (_data_->_state_ != 0) {
		while (!g_task_get_completed (_data_->_async_result)) {
			g_main_context_iteration (g_task_get_context (_data_->_async_result), TRUE);
		}
	}
	g_object_unref (_data_->_async_result);
	return FALSE;
}

static void
ft_stats_manager_process_item_data_free (gpointer _data)
{
	FtStatsManagerProcessItemData* _data_;
	_data_ = _data;
	ft_stats_manager_item_destroy (&_data_->item);
	_g_object_unref0 (_data_->self);
	g_slice_free (FtStatsManagerProcessItemData, _data_);
}

static void
ft_stats_manager_process_item (FtStatsManager* self,
                               FtStatsManagerItem* item,
                               GAsyncReadyCallback _callback_,
                               gpointer _user_data_)
{
	FtStatsManagerProcessItemData* _data_;
	FtStatsManager* _tmp0_;
	FtStatsManagerItem _tmp1_;
	FtStatsManagerItem _tmp2_;
	FtStatsManagerItem _tmp3_ = {0};
	g_return_if_fail (self != NULL);
	g_return_if_fail (item != NULL);
	_data_ = g_slice_new0 (FtStatsManagerProcessItemData);
	_data_->_async_result = g_task_new (G_OBJECT (self), NULL, _callback_, _user_data_);
	g_task_set_task_data (_data_->_async_result, _data_, ft_stats_manager_process_item_data_free);
	_tmp0_ = _g_object_ref0 (self);
	_data_->self = _tmp0_;
	_tmp1_ = *item;
	_tmp2_ = _tmp1_;
	ft_stats_manager_item_copy (&_tmp2_, &_tmp3_);
	ft_stats_manager_item_destroy (&_data_->item);
	_data_->item = _tmp3_;
	ft_stats_manager_process_item_co (_data_);
}

static void
ft_stats_manager_process_item_finish (FtStatsManager* self,
                                      GAsyncResult* _res_,
                                      GError** error)
{
	FtStatsManagerProcessItemData* _data_;
	_data_ = g_task_propagate_pointer (G_TASK (_res_), error);
	if (NULL == _data_) {
		return;
	}
}

static FtStatsManagerSegment*
_vala_array_dup20 (FtStatsManagerSegment* self,
                   gssize length)
{
	if (length > 0) {
		FtStatsManagerSegment* result;
		gssize i;
		result = g_new0 (FtStatsManagerSegment, length);
		for (i = 0; i < length; i++) {
			FtStatsManagerSegment _tmp0_;
			FtStatsManagerSegment _tmp1_ = {0};
			_tmp0_ = self[i];
			ft_stats_manager_segment_copy (&_tmp0_, &_tmp1_);
			result[i] = _tmp1_;
		}
		return result;
	}
	return NULL;
}

static void
ft_stats_manager_process_item_ready (GObject* source_object,
                                     GAsyncResult* _res_,
                                     gpointer _user_data_)
{
	FtStatsManagerProcessItemData* _data_;
	_data_ = _user_data_;
	_data_->_source_object_ = source_object;
	_data_->_res_ = _res_;
	ft_stats_manager_process_item_co (_data_);
}

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

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

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

static gboolean
ft_stats_manager_process_item_co (FtStatsManagerProcessItemData* _data_)
{
	switch (_data_->_state_) {
		case 0:
		goto _state_0;
		case 1:
		goto _state_1;
		case 2:
		goto _state_2;
		case 3:
		goto _state_3;
		default:
		g_assert_not_reached ();
	}
	_state_0:
	_data_->_tmp0_ = _data_->item;
	_data_->_tmp1_ = _data_->_tmp0_.category;
	_data_->_tmp2_ = g_strdup (_data_->_tmp1_);
	_data_->category = _data_->_tmp2_;
	_data_->_tmp3_ = _data_->item;
	_data_->source_id = _data_->_tmp3_.source_id;
	_data_->_tmp4_ = _data_->item;
	_data_->_tmp5_ = _data_->_tmp4_.segments;
	_data_->_tmp5__length1 = _data_->_tmp4_.segments_length1;
	_data_->_tmp6_ = (_data_->_tmp5_ != NULL) ? _vala_array_dup20 (_data_->_tmp5_, _data_->_tmp5__length1) : _data_->_tmp5_;
	_data_->_tmp6__length1 = _data_->_tmp5__length1;
	_data_->segments = _data_->_tmp6_;
	_data_->segments_length1 = _data_->_tmp6__length1;
	_data_->_segments_size_ = _data_->segments_length1;
	_data_->_tmp7_ = ft_database_get_repository ();
	_data_->_tmp8_ = _g_object_ref0 (_data_->_tmp7_);
	_data_->repository = _data_->_tmp8_;
	_data_->_tmp9_ = _data_->repository;
	_data_->_tmp10_ = _data_->category;
	_data_->_tmp11_ = _data_->segments;
	_data_->_tmp11__length1 = _data_->segments_length1;
	_data_->_tmp12_ = _data_->_tmp11_[0];
	_data_->_state_ = 1;
	ft_stats_manager_fetch_entries (_data_->self, _data_->_tmp9_, _data_->_tmp10_, _data_->_tmp12_.timestamp, _data_->source_id, ft_stats_manager_process_item_ready, _data_);
	return FALSE;
	_state_1:
	_data_->_tmp13_ = ft_stats_manager_fetch_entries_finish (_data_->self, _data_->_res_, &_data_->_inner_error0_);
	_data_->entries = _data_->_tmp13_;
	if (G_UNLIKELY (_data_->_inner_error0_ != NULL)) {
		g_task_return_error (_data_->_async_result, _data_->_inner_error0_);
		_g_object_unref0 (_data_->repository);
		_data_->segments = (_vala_FtStatsManagerSegment_array_free (_data_->segments, _data_->segments_length1), NULL);
		_g_free0 (_data_->category);
		g_object_unref (_data_->_async_result);
		return FALSE;
	}
	_data_->entry_index = 0;
	_data_->_tmp14_ = _data_->repository;
	_data_->_tmp15_ = g_object_new (gom_resource_group_get_type (), "repository", _data_->_tmp14_, "resource-type", FT_TYPE_STATS_ENTRY, "is-writable", TRUE, NULL);
	_data_->_tmp16_ = G_IS_INITIALLY_UNOWNED (_data_->_tmp15_) ? g_object_ref_sink (_data_->_tmp15_) : _data_->_tmp15_;
	_data_->to_save = G_TYPE_CHECK_INSTANCE_CAST (_data_->_tmp16_, gom_resource_group_get_type (), GomResourceGroup);
	_data_->to_save_count = 0;
	_data_->_tmp17_ = _data_->repository;
	_data_->_tmp18_ = g_object_new (gom_resource_group_get_type (), "repository", _data_->_tmp17_, "resource-type", FT_TYPE_STATS_ENTRY, "is-writable", TRUE, NULL);
	_data_->_tmp19_ = G_IS_INITIALLY_UNOWNED (_data_->_tmp18_) ? g_object_ref_sink (_data_->_tmp18_) : _data_->_tmp18_;
	_data_->to_delete = G_TYPE_CHECK_INSTANCE_CAST (_data_->_tmp19_, gom_resource_group_get_type (), GomResourceGroup);
	_data_->to_delete_count = 0;
	_data_->_tmp20_ = g_new0 (FtStatsEntry*, 0 + 1);
	_data_->saved_entries = _data_->_tmp20_;
	_data_->saved_entries_length1 = 0;
	_data_->_saved_entries_size_ = _data_->saved_entries_length1;
	_data_->_tmp21_ = g_new0 (FtStatsEntry*, 0 + 1);
	_data_->deleted_entries = _data_->_tmp21_;
	_data_->deleted_entries_length1 = 0;
	_data_->_deleted_entries_size_ = _data_->deleted_entries_length1;
	_data_->_tmp22_ = _data_->entries;
	_data_->_tmp23_ = gom_resource_group_get_count (_data_->_tmp22_);
	_data_->_tmp24_ = _data_->_tmp23_;
	if (_data_->_tmp24_ > ((guint) 0)) {
		_data_->_tmp25_ = _data_->entries;
		_data_->_tmp26_ = _data_->entries;
		_data_->_tmp27_ = gom_resource_group_get_count (_data_->_tmp26_);
		_data_->_tmp28_ = _data_->_tmp27_;
		_data_->_state_ = 2;
		gom_resource_group_fetch_async (_data_->_tmp25_, 0U, _data_->_tmp28_, ft_stats_manager_process_item_ready, _data_);
		return FALSE;
		_state_2:
		gom_resource_group_fetch_finish (_data_->_tmp25_, _data_->_res_, &_data_->_inner_error0_);
		if (G_UNLIKELY (_data_->_inner_error0_ != NULL)) {
			g_task_return_error (_data_->_async_result, _data_->_inner_error0_);
			_data_->deleted_entries = (_vala_array_free (_data_->deleted_entries, _data_->deleted_entries_length1, (GDestroyNotify) g_object_unref), NULL);
			_data_->saved_entries = (_vala_array_free (_data_->saved_entries, _data_->saved_entries_length1, (GDestroyNotify) g_object_unref), NULL);
			_g_object_unref0 (_data_->to_delete);
			_g_object_unref0 (_data_->to_save);
			_g_object_unref0 (_data_->entries);
			_g_object_unref0 (_data_->repository);
			_data_->segments = (_vala_FtStatsManagerSegment_array_free (_data_->segments, _data_->segments_length1), NULL);
			_g_free0 (_data_->category);
			g_object_unref (_data_->_async_result);
			return FALSE;
		}
	}
	_data_->_tmp29_ = _data_->segments;
	_data_->_tmp29__length1 = _data_->segments_length1;
	{
		_data_->segment_collection_length1 = 0;
		_data_->_segment_collection_size_ = 0;
		_data_->segment_collection = _data_->_tmp29_;
		_data_->segment_collection_length1 = _data_->_tmp29__length1;
		for (_data_->segment_it = 0; _data_->segment_it < _data_->segment_collection_length1; _data_->segment_it = _data_->segment_it + 1) {
			_data_->_tmp30_ = _data_->segment_collection[_data_->segment_it];
			memset (&_data_->_tmp31_, 0, sizeof (FtStatsManagerSegment));
			ft_stats_manager_segment_copy (&_data_->_tmp30_, &_data_->_tmp31_);
			_data_->segment = _data_->_tmp31_;
			{
				if (!ft_stats_manager_segment_is_valid (&_data_->segment)) {
					_g_object_unref0 (_data_->entry);
					ft_stats_manager_segment_destroy (&_data_->segment);
					continue;
				}
				_data_->_tmp32_ = _data_->entries;
				_data_->_tmp33_ = gom_resource_group_get_count (_data_->_tmp32_);
				_data_->_tmp34_ = _data_->_tmp33_;
				if (((guint) _data_->entry_index) < _data_->_tmp34_) {
					_data_->_tmp35_ = _data_->entries;
					_data_->_tmp36_ = gom_resource_group_get_index (_data_->_tmp35_, (guint) _data_->entry_index);
					_data_->_tmp37_ = _g_object_ref0 (G_TYPE_CHECK_INSTANCE_CAST (_data_->_tmp36_, FT_TYPE_STATS_ENTRY, FtStatsEntry));
					_g_object_unref0 (_data_->entry);
					_data_->entry = _data_->_tmp37_;
					_data_->_tmp38_ = _data_->entry_index;
					_data_->entry_index = _data_->_tmp38_ + 1;
					_data_->_tmp40_ = _data_->entry;
					_data_->_tmp41_ = ft_stats_entry_get_time (_data_->_tmp40_);
					_data_->_tmp42_ = _data_->_tmp41_;
					_data_->_tmp43_ = _data_->segment;
					if (_data_->_tmp42_ == _data_->_tmp43_.timestamp) {
						_data_->_tmp44_ = _data_->entry;
						_data_->_tmp45_ = ft_stats_entry_get_duration (_data_->_tmp44_);
						_data_->_tmp46_ = _data_->_tmp45_;
						_data_->_tmp47_ = _data_->segment;
						_data_->_tmp39_ = _data_->_tmp46_ == _data_->_tmp47_.duration;
					} else {
						_data_->_tmp39_ = FALSE;
					}
					if (_data_->_tmp39_) {
						_g_object_unref0 (_data_->entry);
						ft_stats_manager_segment_destroy (&_data_->segment);
						continue;
					}
					_data_->_tmp48_ = _data_->entry;
					_data_->_tmp49_ = ft_stats_entry_copy (_data_->_tmp48_);
					_vala_array_add29 (&_data_->deleted_entries, &_data_->deleted_entries_length1, &_data_->_deleted_entries_size_, _data_->_tmp49_);
				} else {
					_data_->_tmp50_ = ft_stats_entry_new ();
					_g_object_unref0 (_data_->entry);
					_data_->entry = _data_->_tmp50_;
					_data_->_tmp51_ = _data_->entry;
					_data_->_tmp52_ = _data_->repository;
					g_object_set ((GomResource*) _data_->_tmp51_, "repository", _data_->_tmp52_, NULL);
				}
				_data_->_tmp53_ = _data_->segment;
				_data_->_tmp54_ = _data_->_tmp53_.datetime;
				memset (&_data_->_tmp55_, 0, sizeof (GDate));
				_data_->_tmp56_ = 0LL;
				ft_stats_manager_transform_datetime (_data_->self, _data_->_tmp54_, &_data_->_tmp55_, &_data_->_tmp56_);
				_data_->date = _data_->_tmp55_;
				_data_->offset = _data_->_tmp56_;
				_data_->_tmp57_ = _data_->entry;
				_data_->_tmp58_ = _data_->category;
				ft_stats_entry_set_category (_data_->_tmp57_, _data_->_tmp58_);
				_data_->_tmp59_ = _data_->entry;
				_data_->_tmp60_ = _data_->segment;
				ft_stats_entry_set_time (_data_->_tmp59_, _data_->_tmp60_.timestamp);
				_data_->_tmp61_ = _data_->entry;
				_data_->_tmp62_ = _data_->date;
				_data_->_tmp63_ = ft_database_serialize_date (&_data_->_tmp62_);
				_data_->_tmp64_ = _data_->_tmp63_;
				ft_stats_entry_set_date (_data_->_tmp61_, _data_->_tmp64_);
				_g_free0 (_data_->_tmp64_);
				_data_->_tmp65_ = _data_->entry;
				ft_stats_entry_set_offset (_data_->_tmp65_, _data_->offset);
				_data_->_tmp66_ = _data_->entry;
				_data_->_tmp67_ = _data_->segment;
				ft_stats_entry_set_duration (_data_->_tmp66_, _data_->_tmp67_.duration);
				_data_->_tmp68_ = _data_->entry;
				ft_stats_entry_set_source_id (_data_->_tmp68_, _data_->source_id);
				_data_->_tmp69_ = _data_->to_save;
				_data_->_tmp70_ = _data_->entry;
				gom_resource_group_append (_data_->_tmp69_, (GomResource*) _data_->_tmp70_);
				_data_->_tmp71_ = _data_->to_save_count;
				_data_->to_save_count = _data_->_tmp71_ + 1;
				_data_->_tmp72_ = _data_->entry;
				_data_->_tmp73_ = _g_object_ref0 (_data_->_tmp72_);
				_vala_array_add30 (&_data_->saved_entries, &_data_->saved_entries_length1, &_data_->_saved_entries_size_, _data_->_tmp73_);
				_g_object_unref0 (_data_->entry);
				ft_stats_manager_segment_destroy (&_data_->segment);
			}
		}
	}
	_data_->_tmp74_ = _data_->to_save;
	gom_resource_group_write_sync (_data_->_tmp74_, &_data_->_inner_error0_);
	if (G_UNLIKELY (_data_->_inner_error0_ != NULL)) {
		g_task_return_error (_data_->_async_result, _data_->_inner_error0_);
		_data_->deleted_entries = (_vala_array_free (_data_->deleted_entries, _data_->deleted_entries_length1, (GDestroyNotify) g_object_unref), NULL);
		_data_->saved_entries = (_vala_array_free (_data_->saved_entries, _data_->saved_entries_length1, (GDestroyNotify) g_object_unref), NULL);
		_g_object_unref0 (_data_->to_delete);
		_g_object_unref0 (_data_->to_save);
		_g_object_unref0 (_data_->entries);
		_g_object_unref0 (_data_->repository);
		_data_->segments = (_vala_FtStatsManagerSegment_array_free (_data_->segments, _data_->segments_length1), NULL);
		_g_free0 (_data_->category);
		g_object_unref (_data_->_async_result);
		return FALSE;
	}
	while (TRUE) {
		_data_->_tmp75_ = _data_->entries;
		_data_->_tmp76_ = gom_resource_group_get_count (_data_->_tmp75_);
		_data_->_tmp77_ = _data_->_tmp76_;
		if (!(((guint) _data_->entry_index) < _data_->_tmp77_)) {
			break;
		}
		_data_->_tmp78_ = _data_->entries;
		_data_->_tmp79_ = gom_resource_group_get_index (_data_->_tmp78_, (guint) _data_->entry_index);
		_data_->_tmp80_ = _g_object_ref0 (G_TYPE_CHECK_INSTANCE_CAST (_data_->_tmp79_, FT_TYPE_STATS_ENTRY, FtStatsEntry));
		_data_->_vala1_entry = _data_->_tmp80_;
		_data_->_tmp81_ = _data_->entry_index;
		_data_->entry_index = _data_->_tmp81_ + 1;
		_data_->_tmp82_ = _data_->_vala1_entry;
		_vala_assert (_data_->_tmp82_ != NULL, "entry != null");
		_data_->_tmp83_ = _data_->_vala1_entry;
		_data_->_tmp84_ = _g_object_ref0 (_data_->_tmp83_);
		_vala_array_add31 (&_data_->deleted_entries, &_data_->deleted_entries_length1, &_data_->_deleted_entries_size_, _data_->_tmp84_);
		_data_->_tmp85_ = _data_->to_delete;
		_data_->_tmp86_ = _data_->_vala1_entry;
		gom_resource_group_append (_data_->_tmp85_, (GomResource*) _data_->_tmp86_);
		_data_->_tmp87_ = _data_->to_delete_count;
		_data_->to_delete_count = _data_->_tmp87_ + 1;
		_g_object_unref0 (_data_->_vala1_entry);
	}
	_data_->_tmp88_ = _data_->to_delete;
	if (_data_->_tmp88_ != NULL) {
		_data_->_tmp89_ = _data_->to_delete;
		_data_->_state_ = 3;
		gom_resource_group_delete_async (_data_->_tmp89_, ft_stats_manager_process_item_ready, _data_);
		return FALSE;
		_state_3:
		gom_resource_group_delete_finish (_data_->_tmp89_, _data_->_res_, &_data_->_inner_error0_);
		if (G_UNLIKELY (_data_->_inner_error0_ != NULL)) {
			g_task_return_error (_data_->_async_result, _data_->_inner_error0_);
			_data_->deleted_entries = (_vala_array_free (_data_->deleted_entries, _data_->deleted_entries_length1, (GDestroyNotify) g_object_unref), NULL);
			_data_->saved_entries = (_vala_array_free (_data_->saved_entries, _data_->saved_entries_length1, (GDestroyNotify) g_object_unref), NULL);
			_g_object_unref0 (_data_->to_delete);
			_g_object_unref0 (_data_->to_save);
			_g_object_unref0 (_data_->entries);
			_g_object_unref0 (_data_->repository);
			_data_->segments = (_vala_FtStatsManagerSegment_array_free (_data_->segments, _data_->segments_length1), NULL);
			_g_free0 (_data_->category);
			g_object_unref (_data_->_async_result);
			return FALSE;
		}
	}
	_data_->_tmp90_ = _data_->saved_entries;
	_data_->_tmp90__length1 = _data_->saved_entries_length1;
	{
		_data_->entry_collection_length1 = 0;
		_data_->_entry_collection_size_ = 0;
		_data_->entry_collection = _data_->_tmp90_;
		_data_->entry_collection_length1 = _data_->_tmp90__length1;
		for (_data_->entry_it = 0; _data_->entry_it < _data_->entry_collection_length1; _data_->entry_it = _data_->entry_it + 1) {
			_data_->_tmp91_ = _g_object_ref0 (_data_->entry_collection[_data_->entry_it]);
			_data_->_vala2_entry = _data_->_tmp91_;
			{
				_data_->_tmp92_ = _data_->_vala2_entry;
				g_signal_emit (_data_->self, ft_stats_manager_signals[FT_STATS_MANAGER_ENTRY_SAVED_SIGNAL], 0, _data_->_tmp92_);
				_g_object_unref0 (_data_->_vala2_entry);
			}
		}
	}
	_data_->_tmp93_ = _data_->deleted_entries;
	_data_->_tmp93__length1 = _data_->deleted_entries_length1;
	{
		_data_->_vala1_entry_collection_length1 = 0;
		_data_->__vala1_entry_collection_size_ = 0;
		_data_->_vala1_entry_collection = _data_->_tmp93_;
		_data_->_vala1_entry_collection_length1 = _data_->_tmp93__length1;
		for (_data_->_vala1_entry_it = 0; _data_->_vala1_entry_it < _data_->_vala1_entry_collection_length1; _data_->_vala1_entry_it = _data_->_vala1_entry_it + 1) {
			_data_->_tmp94_ = _g_object_ref0 (_data_->_vala1_entry_collection[_data_->_vala1_entry_it]);
			_data_->_vala3_entry = _data_->_tmp94_;
			{
				_data_->_tmp95_ = _data_->_vala3_entry;
				g_signal_emit (_data_->self, ft_stats_manager_signals[FT_STATS_MANAGER_ENTRY_DELETED_SIGNAL], 0, _data_->_tmp95_);
				_g_object_unref0 (_data_->_vala3_entry);
			}
		}
	}
	_data_->deleted_entries = (_vala_array_free (_data_->deleted_entries, _data_->deleted_entries_length1, (GDestroyNotify) g_object_unref), NULL);
	_data_->saved_entries = (_vala_array_free (_data_->saved_entries, _data_->saved_entries_length1, (GDestroyNotify) g_object_unref), NULL);
	_g_object_unref0 (_data_->to_delete);
	_g_object_unref0 (_data_->to_save);
	_g_object_unref0 (_data_->entries);
	_g_object_unref0 (_data_->repository);
	_data_->segments = (_vala_FtStatsManagerSegment_array_free (_data_->segments, _data_->segments_length1), NULL);
	_g_free0 (_data_->category);
	g_task_return_pointer (_data_->_async_result, _data_, NULL);
	if (_data_->_state_ != 0) {
		while (!g_task_get_completed (_data_->_async_result)) {
			g_main_context_iteration (g_task_get_context (_data_->_async_result), TRUE);
		}
	}
	g_object_unref (_data_->_async_result);
	return FALSE;
}

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

static void
ft_stats_manager_process_queue (FtStatsManager* self,
                                GAsyncReadyCallback _callback_,
                                gpointer _user_data_)
{
	FtStatsManagerProcessQueueData* _data_;
	FtStatsManager* _tmp0_;
	g_return_if_fail (self != NULL);
	_data_ = g_slice_new0 (FtStatsManagerProcessQueueData);
	_data_->_async_result = g_task_new (G_OBJECT (self), NULL, _callback_, _user_data_);
	g_task_set_task_data (_data_->_async_result, _data_, ft_stats_manager_process_queue_data_free);
	_tmp0_ = _g_object_ref0 (self);
	_data_->self = _tmp0_;
	ft_stats_manager_process_queue_co (_data_);
}

static void
ft_stats_manager_process_queue_finish (FtStatsManager* self,
                                       GAsyncResult* _res_)
{
	FtStatsManagerProcessQueueData* _data_;
	_data_ = g_task_propagate_pointer (G_TASK (_res_), NULL);
}

static void
ft_stats_manager_process_queue_ready (GObject* source_object,
                                      GAsyncResult* _res_,
                                      gpointer _user_data_)
{
	FtStatsManagerProcessQueueData* _data_;
	_data_ = _user_data_;
	_data_->_source_object_ = source_object;
	_data_->_res_ = _res_;
	ft_stats_manager_process_queue_co (_data_);
}

static gboolean
ft_stats_manager_process_queue_co (FtStatsManagerProcessQueueData* _data_)
{
	switch (_data_->_state_) {
		case 0:
		goto _state_0;
		case 1:
		goto _state_1;
		default:
		g_assert_not_reached ();
	}
	_state_0:
	if (_data_->self->priv->is_processing) {
		g_task_return_pointer (_data_->_async_result, _data_, NULL);
		if (_data_->_state_ != 0) {
			while (!g_task_get_completed (_data_->_async_result)) {
				g_main_context_iteration (g_task_get_context (_data_->_async_result), TRUE);
			}
		}
		g_object_unref (_data_->_async_result);
		return FALSE;
	}
	_data_->self->priv->is_processing = TRUE;
	while (TRUE) {
		_data_->_tmp0_ = _data_->self->priv->queue;
		_data_->_tmp1_ = ft_async_queue_pop (_data_->_tmp0_);
		_ft_stats_manager_item_free0 (_data_->item);
		_data_->item = (FtStatsManagerItem*) _data_->_tmp1_;
		_data_->_tmp2_ = _data_->item;
		if (!(_data_->_tmp2_ != NULL)) {
			break;
		}
		{
			_data_->_tmp3_ = _data_->item;
			_data_->_tmp4_ = *_data_->_tmp3_;
			_data_->_state_ = 1;
			ft_stats_manager_process_item (_data_->self, &_data_->_tmp4_, ft_stats_manager_process_queue_ready, _data_);
			return FALSE;
			_state_1:
			ft_stats_manager_process_item_finish (_data_->self, _data_->_res_, &_data_->_inner_error0_);
			if (G_UNLIKELY (_data_->_inner_error0_ != NULL)) {
				goto __catch0_g_error;
			}
		}
		goto __finally0;
		__catch0_g_error:
		{
			_data_->_error_ = _data_->_inner_error0_;
			_data_->_inner_error0_ = NULL;
			_data_->_tmp5_ = _data_->_error_;
			_data_->_tmp6_ = _data_->_tmp5_->message;
			g_warning ("stats-manager.vala:405: Error while processing stats item: %s", _data_->_tmp6_);
			_g_error_free0 (_data_->_error_);
		}
		__finally0:
		if (G_UNLIKELY (_data_->_inner_error0_ != NULL)) {
			_ft_stats_manager_item_free0 (_data_->item);
			g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _data_->_inner_error0_->message, g_quark_to_string (_data_->_inner_error0_->domain), _data_->_inner_error0_->code);
			g_clear_error (&_data_->_inner_error0_);
			g_object_unref (_data_->_async_result);
			return FALSE;
		}
	}
	_data_->self->priv->is_processing = FALSE;
	_data_->_tmp7_ = _data_->self->priv->flush_callbacks;
	_data_->_tmp7__length1 = _data_->self->priv->flush_callbacks_length1;
	{
		_data_->callback_collection_length1 = 0;
		_data_->_callback_collection_size_ = 0;
		_data_->callback_collection = _data_->_tmp7_;
		_data_->callback_collection_length1 = _data_->_tmp7__length1;
		for (_data_->callback_it = 0; _data_->callback_it < _data_->callback_collection_length1; _data_->callback_it = _data_->callback_it + 1) {
			_data_->callback = _data_->callback_collection[_data_->callback_it];
			{
				_data_->_tmp8_ = _data_->callback;
				_data_->_tmp9_ = _data_->_tmp8_->func;
				_data_->_tmp9__target = _data_->_tmp8_->func_target;
				_data_->_tmp9_ (_data_->_tmp9__target);
			}
		}
	}
	_data_->_tmp10_ = g_new0 (FtAsyncCallback*, 0 + 1);
	_data_->self->priv->flush_callbacks = (_vala_array_free (_data_->self->priv->flush_callbacks, _data_->self->priv->flush_callbacks_length1, (GDestroyNotify) ft_async_callback_free), NULL);
	_data_->self->priv->flush_callbacks = _data_->_tmp10_;
	_data_->self->priv->flush_callbacks_length1 = 0;
	_data_->self->priv->_flush_callbacks_size_ = _data_->self->priv->flush_callbacks_length1;
	_ft_stats_manager_item_free0 (_data_->item);
	g_task_return_pointer (_data_->_async_result, _data_, NULL);
	if (_data_->_state_ != 0) {
		while (!g_task_get_completed (_data_->_async_result)) {
			g_main_context_iteration (g_task_get_context (_data_->_async_result), TRUE);
		}
	}
	g_object_unref (_data_->_async_result);
	return FALSE;
}

static FtStatsManagerSegment*
_vala_array_dup21 (FtStatsManagerSegment* self,
                   gssize length)
{
	if (length > 0) {
		FtStatsManagerSegment* result;
		gssize i;
		result = g_new0 (FtStatsManagerSegment, length);
		for (i = 0; i < length; i++) {
			FtStatsManagerSegment _tmp0_;
			FtStatsManagerSegment _tmp1_ = {0};
			_tmp0_ = self[i];
			ft_stats_manager_segment_copy (&_tmp0_, &_tmp1_);
			result[i] = _tmp1_;
		}
		return result;
	}
	return NULL;
}

static gpointer
_ft_stats_manager_item_dup0 (gpointer self)
{
	return self ? ft_stats_manager_item_dup (self) : NULL;
}

static void
ft_stats_manager_track_internal (FtStatsManager* self,
                                 const gchar* category,
                                 gint64 source_id,
                                 FtStatsManagerSegment* segments,
                                 gint segments_length1)
{
	FtAsyncQueue* _tmp0_;
	gchar* _tmp1_;
	FtStatsManagerSegment* _tmp2_;
	gint _tmp2__length1;
	FtStatsManagerItem _tmp3_ = {0};
	FtStatsManagerItem _tmp4_;
	FtStatsManagerItem* _tmp5_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (category != NULL);
	if (segments_length1 == 0) {
		segments = (_vala_FtStatsManagerSegment_array_free (segments, segments_length1), NULL);
		return;
	}
	_tmp0_ = self->priv->queue;
	_tmp1_ = g_strdup (category);
	_tmp2_ = (segments != NULL) ? _vala_array_dup21 (segments, segments_length1) : segments;
	_tmp2__length1 = segments_length1;
	memset (&_tmp3_, 0, sizeof (FtStatsManagerItem));
	_g_free0 (_tmp3_.category);
	_tmp3_.category = _tmp1_;
	_tmp3_.source_id = source_id;
	_tmp3_.segments = (_vala_FtStatsManagerSegment_array_free (_tmp3_.segments, _tmp3_.segments_length1), NULL);
	_tmp3_.segments = _tmp2_;
	_tmp3_.segments_length1 = _tmp2__length1;
	_tmp3_._segments_size_ = _tmp3_.segments_length1;
	_tmp4_ = _tmp3_;
	_tmp5_ = _ft_stats_manager_item_dup0 (&_tmp4_);
	ft_async_queue_push (_tmp0_, _tmp5_);
	ft_stats_manager_item_destroy (&_tmp4_);
	ft_stats_manager_process_queue (self, NULL, NULL);
	segments = (_vala_FtStatsManagerSegment_array_free (segments, segments_length1), NULL);
}

static FtStatsManagerSegment*
_vala_array_dup22 (FtStatsManagerSegment* self,
                   gssize length)
{
	if (length > 0) {
		FtStatsManagerSegment* result;
		gssize i;
		result = g_new0 (FtStatsManagerSegment, length);
		for (i = 0; i < length; i++) {
			FtStatsManagerSegment _tmp0_;
			FtStatsManagerSegment _tmp1_ = {0};
			_tmp0_ = self[i];
			ft_stats_manager_segment_copy (&_tmp0_, &_tmp1_);
			result[i] = _tmp1_;
		}
		return result;
	}
	return NULL;
}

void
ft_stats_manager_track (FtStatsManager* self,
                        const gchar* category,
                        gint64 timestamp,
                        gint64 duration,
                        gint64 source_id)
{
	gboolean _tmp0_ = FALSE;
	FtStatsManagerSegment* segments = NULL;
	gint _tmp1_ = 0;
	FtStatsManagerSegment* _tmp2_;
	gint segments_length1;
	gint _segments_size_;
	FtStatsManagerSegment* _tmp3_;
	gint _tmp3__length1;
	FtStatsManagerSegment* _tmp4_;
	gint _tmp4__length1;
	g_return_if_fail (self != NULL);
	g_return_if_fail (category != NULL);
	if (ft_timestamp_is_undefined (timestamp)) {
		_tmp0_ = TRUE;
	} else {
		_tmp0_ = duration <= ((gint64) 0);
	}
	if (_tmp0_) {
		return;
	}
	_tmp2_ = ft_stats_manager_split (self, timestamp, duration, &_tmp1_);
	segments = _tmp2_;
	segments_length1 = _tmp1_;
	_segments_size_ = segments_length1;
	_tmp3_ = segments;
	_tmp3__length1 = segments_length1;
	_tmp4_ = (_tmp3_ != NULL) ? _vala_array_dup22 (_tmp3_, _tmp3__length1) : _tmp3_;
	_tmp4__length1 = _tmp3__length1;
	ft_stats_manager_track_internal (self, category, source_id, _tmp4_, (gint) _tmp4__length1);
	segments = (_vala_FtStatsManagerSegment_array_free (segments, segments_length1), NULL);
}

/**
         * Finds the intersection of two arrays of segments.
         * Returns a new array containing segments that represent overlapping time periods.
         * Assume that both arrays are sorted.
         */
static void
_vala_array_add32 (FtStatsManagerSegment* * array,
                   gint* length,
                   gint* size,
                   const FtStatsManagerSegment* value)
{
	if ((*length) == (*size)) {
		*size = (*size) ? (2 * (*size)) : 4;
		*array = g_renew (FtStatsManagerSegment, *array, *size);
	}
	(*array)[(*length)++] = *value;
}

static FtStatsManagerSegment*
ft_stats_manager_intersect_segments (FtStatsManager* self,
                                     FtStatsManagerSegment* a,
                                     gint a_length1,
                                     FtStatsManagerSegment* b,
                                     gint b_length1,
                                     gint* result_length1)
{
	FtStatsManagerSegment* _result_ = NULL;
	FtStatsManagerSegment* _tmp0_;
	gint _result__length1;
	gint __result__size_;
	gint b_index = 0;
	gint b_length = 0;
	FtStatsManagerSegment* _tmp24_;
	gint _tmp24__length1;
	FtStatsManagerSegment* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = g_new0 (FtStatsManagerSegment, 0);
	_result_ = _tmp0_;
	_result__length1 = 0;
	__result__size_ = _result__length1;
	b_index = 0;
	b_length = b_length1;
	{
		FtStatsManagerSegment* segment_a_collection = NULL;
		gint segment_a_collection_length1 = 0;
		gint _segment_a_collection_size_ = 0;
		gint segment_a_it = 0;
		segment_a_collection = a;
		segment_a_collection_length1 = a_length1;
		for (segment_a_it = 0; segment_a_it < segment_a_collection_length1; segment_a_it = segment_a_it + 1) {
			FtStatsManagerSegment _tmp1_;
			FtStatsManagerSegment _tmp2_ = {0};
			FtStatsManagerSegment segment_a = {0};
			_tmp1_ = segment_a_collection[segment_a_it];
			ft_stats_manager_segment_copy (&_tmp1_, &_tmp2_);
			segment_a = _tmp2_;
			{
				gint64 a_start = 0LL;
				FtStatsManagerSegment _tmp3_;
				gint64 a_end = 0LL;
				FtStatsManagerSegment _tmp4_;
				_tmp3_ = segment_a;
				a_start = _tmp3_.timestamp;
				_tmp4_ = segment_a;
				a_end = a_start + _tmp4_.duration;
				while (TRUE) {
					gboolean _tmp5_ = FALSE;
					gint _tmp8_;
					if (b_index < b_length) {
						FtStatsManagerSegment _tmp6_;
						FtStatsManagerSegment _tmp7_;
						_tmp6_ = b[b_index];
						_tmp7_ = b[b_index];
						_tmp5_ = (_tmp6_.timestamp + _tmp7_.duration) <= a_start;
					} else {
						_tmp5_ = FALSE;
					}
					if (!_tmp5_) {
						break;
					}
					_tmp8_ = b_index;
					b_index = _tmp8_ + 1;
				}
				if (b_index >= b_length) {
					ft_stats_manager_segment_destroy (&segment_a);
					break;
				}
				{
					gint tmp_index = 0;
					tmp_index = b_index;
					{
						gboolean _tmp9_ = FALSE;
						_tmp9_ = TRUE;
						while (TRUE) {
							FtStatsManagerSegment segment_b = {0};
							FtStatsManagerSegment _tmp11_;
							FtStatsManagerSegment _tmp12_;
							FtStatsManagerSegment _tmp13_ = {0};
							gint64 b_start = 0LL;
							FtStatsManagerSegment _tmp14_;
							gint64 b_end = 0LL;
							FtStatsManagerSegment _tmp15_;
							gboolean _tmp16_ = FALSE;
							if (!_tmp9_) {
								gint _tmp10_;
								_tmp10_ = tmp_index;
								tmp_index = _tmp10_ + 1;
							}
							_tmp9_ = FALSE;
							if (!(tmp_index < b_length)) {
								break;
							}
							_tmp11_ = b[tmp_index];
							_tmp12_ = _tmp11_;
							ft_stats_manager_segment_copy (&_tmp12_, &_tmp13_);
							segment_b = _tmp13_;
							_tmp14_ = segment_b;
							b_start = _tmp14_.timestamp;
							_tmp15_ = segment_b;
							b_end = b_start + _tmp15_.duration;
							if (b_start >= a_end) {
								ft_stats_manager_segment_destroy (&segment_b);
								break;
							}
							if (a_start < b_end) {
								_tmp16_ = a_end > b_start;
							} else {
								_tmp16_ = FALSE;
							}
							if (_tmp16_) {
								gint64 intersection_start = 0LL;
								gint64 intersection_end = 0LL;
								GDateTime* _tmp17_ = NULL;
								GDateTime* _tmp22_;
								FtStatsManagerSegment _tmp23_ = {0};
								intersection_start = MAX (a_start, b_start);
								intersection_end = MIN (a_end, b_end);
								if (intersection_start == a_start) {
									FtStatsManagerSegment _tmp18_;
									GDateTime* _tmp19_;
									_tmp18_ = segment_a;
									_tmp19_ = _tmp18_.datetime;
									_tmp17_ = _tmp19_;
								} else {
									FtStatsManagerSegment _tmp20_;
									GDateTime* _tmp21_;
									_tmp20_ = segment_b;
									_tmp21_ = _tmp20_.datetime;
									_tmp17_ = _tmp21_;
								}
								_tmp22_ = _g_date_time_ref0 (_tmp17_);
								memset (&_tmp23_, 0, sizeof (FtStatsManagerSegment));
								_tmp23_.timestamp = intersection_start;
								_tmp23_.duration = intersection_end - intersection_start;
								_g_date_time_unref0 (_tmp23_.datetime);
								_tmp23_.datetime = _tmp22_;
								_vala_array_add32 (&_result_, &_result__length1, &__result__size_, &_tmp23_);
							}
							ft_stats_manager_segment_destroy (&segment_b);
						}
					}
				}
				ft_stats_manager_segment_destroy (&segment_a);
			}
		}
	}
	_tmp24_ = _result_;
	_tmp24__length1 = _result__length1;
	if (result_length1) {
		*result_length1 = _tmp24__length1;
	}
	result = _tmp24_;
	a = (_vala_FtStatsManagerSegment_array_free (a, a_length1), NULL);
	b = (_vala_FtStatsManagerSegment_array_free (b, b_length1), NULL);
	return result;
}

static Block54Data*
block54_data_ref (Block54Data* _data54_)
{
	g_atomic_int_inc (&_data54_->_ref_count_);
	return _data54_;
}

static void
block54_data_unref (void * _userdata_)
{
	Block54Data* _data54_;
	_data54_ = (Block54Data*) _userdata_;
	if (g_atomic_int_dec_and_test (&_data54_->_ref_count_)) {
		FtStatsManager* self;
		self = _data54_->self;
		_data54_->segments = (_vala_FtStatsManagerSegment_array_free (_data54_->segments, _data54_->segments_length1), NULL);
		_g_object_unref0 (self);
		g_slice_free (Block54Data, _data54_);
	}
}

static void
_vala_array_add33 (FtStatsManagerSegment* * array,
                   gint* length,
                   gint* size,
                   const FtStatsManagerSegment* value)
{
	if ((*length) == (*size)) {
		*size = (*size) ? (2 * (*size)) : 4;
		*array = g_renew (FtStatsManagerSegment, *array, *size);
	}
	(*array)[(*length)++] = *value;
}

static void
__lambda98_ (Block54Data* _data54_,
             FtGap* gap)
{
	FtStatsManager* self;
	gint64 _tmp0_;
	gint64 _tmp1_;
	gint64 _tmp6_;
	gint64 _tmp7_;
	self = _data54_->self;
	g_return_if_fail (gap != NULL);
	_tmp0_ = ft_schedulable_get_start_time ((FtSchedulable*) gap);
	_tmp1_ = _tmp0_;
	if (_tmp1_ > _data54_->timestamp) {
		gint64 _tmp2_;
		gint64 _tmp3_;
		GDateTime* _tmp4_;
		FtStatsManagerSegment _tmp5_ = {0};
		_tmp2_ = ft_schedulable_get_start_time ((FtSchedulable*) gap);
		_tmp3_ = _tmp2_;
		_tmp4_ = ft_stats_manager_transform_timestamp (self, _data54_->timestamp);
		memset (&_tmp5_, 0, sizeof (FtStatsManagerSegment));
		_tmp5_.timestamp = _data54_->timestamp;
		_tmp5_.duration = _tmp3_ - _data54_->timestamp;
		_g_date_time_unref0 (_tmp5_.datetime);
		_tmp5_.datetime = _tmp4_;
		_vala_array_add33 (&_data54_->segments, &_data54_->segments_length1, &_data54_->_segments_size_, &_tmp5_);
	}
	_tmp6_ = ft_schedulable_get_end_time ((FtSchedulable*) gap);
	_tmp7_ = _tmp6_;
	_data54_->timestamp = _tmp7_;
}

static void
___lambda98__gfunc (gconstpointer data,
                    gpointer self)
{
	__lambda98_ (self, (FtGap*) data);
}

static void
_vala_array_add34 (FtStatsManagerSegment* * array,
                   gint* length,
                   gint* size,
                   const FtStatsManagerSegment* value)
{
	if ((*length) == (*size)) {
		*size = (*size) ? (2 * (*size)) : 4;
		*array = g_renew (FtStatsManagerSegment, *array, *size);
	}
	(*array)[(*length)++] = *value;
}

static FtStatsManagerSegment*
_vala_array_dup23 (FtStatsManagerSegment* self,
                   gssize length)
{
	if (length > 0) {
		FtStatsManagerSegment* result;
		gssize i;
		result = g_new0 (FtStatsManagerSegment, length);
		for (i = 0; i < length; i++) {
			FtStatsManagerSegment _tmp0_;
			FtStatsManagerSegment _tmp1_ = {0};
			_tmp0_ = self[i];
			ft_stats_manager_segment_copy (&_tmp0_, &_tmp1_);
			result[i] = _tmp1_;
		}
		return result;
	}
	return NULL;
}

static FtStatsManagerSegment*
_vala_array_dup24 (FtStatsManagerSegment* self,
                   gssize length)
{
	if (length > 0) {
		FtStatsManagerSegment* result;
		gssize i;
		result = g_new0 (FtStatsManagerSegment, length);
		for (i = 0; i < length; i++) {
			FtStatsManagerSegment _tmp0_;
			FtStatsManagerSegment _tmp1_ = {0};
			_tmp0_ = self[i];
			ft_stats_manager_segment_copy (&_tmp0_, &_tmp1_);
			result[i] = _tmp1_;
		}
		return result;
	}
	return NULL;
}

void
ft_stats_manager_track_time_block (FtStatsManager* self,
                                   FtTimeBlock* time_block)
{
	Block54Data* _data54_;
	FtTimeBlockEntry* time_block_entry = NULL;
	FtTimeBlockEntry* _tmp0_;
	gint64 _tmp1_;
	gint64 _tmp2_;
	gchar* category = NULL;
	FtState _tmp3_;
	FtState _tmp4_;
	gchar* _tmp5_;
	FtStatsManagerSegment* _tmp6_;
	const gchar* _tmp7_;
	FtTimeBlockEntry* _tmp12_;
	gboolean _tmp17_ = FALSE;
	gboolean _tmp18_ = FALSE;
	gint64 _tmp19_;
	gint64 _tmp20_;
	FtStatsManagerSegment* _tmp27_;
	gint _tmp27__length1;
	FtStatsManagerSegment* _tmp28_;
	gint _tmp28__length1;
	gint64 _tmp29_;
	gint64 _tmp30_;
	gint64 _tmp31_;
	gint64 _tmp32_;
	gint _tmp33_ = 0;
	FtStatsManagerSegment* _tmp34_;
	gint _tmp35_ = 0;
	FtStatsManagerSegment* _tmp36_;
	const gchar* _tmp37_;
	FtTimeBlockEntry* _tmp38_;
	gint64 _tmp39_;
	gint64 _tmp40_;
	FtStatsManagerSegment* _tmp41_;
	gint _tmp41__length1;
	FtStatsManagerSegment* _tmp42_;
	gint _tmp42__length1;
	g_return_if_fail (self != NULL);
	g_return_if_fail (time_block != NULL);
	_data54_ = g_slice_new0 (Block54Data);
	_data54_->_ref_count_ = 1;
	_data54_->self = g_object_ref (self);
	ft_stats_manager_try_save_time_block (self, time_block);
	_tmp0_ = time_block->entry;
	time_block_entry = _tmp0_;
	_tmp1_ = ft_schedulable_get_start_time ((FtSchedulable*) time_block);
	_tmp2_ = _tmp1_;
	_data54_->timestamp = _tmp2_;
	_tmp3_ = ft_time_block_get_state (time_block);
	_tmp4_ = _tmp3_;
	_tmp5_ = ft_stats_manager_transform_state (self, _tmp4_);
	category = _tmp5_;
	_tmp6_ = g_new0 (FtStatsManagerSegment, 0);
	_data54_->segments = _tmp6_;
	_data54_->segments_length1 = 0;
	_data54_->_segments_size_ = _data54_->segments_length1;
	if (ft_time_block_get_status (time_block) == FT_TIME_BLOCK_STATUS_SCHEDULED) {
		_g_free0 (category);
		block54_data_unref (_data54_);
		_data54_ = NULL;
		return;
	}
	_tmp7_ = category;
	if (_tmp7_ == NULL) {
		FtState _tmp8_;
		FtState _tmp9_;
		gchar* _tmp10_;
		gchar* _tmp11_;
		_tmp8_ = ft_time_block_get_state (time_block);
		_tmp9_ = _tmp8_;
		_tmp10_ = ft_state_to_string (_tmp9_);
		_tmp11_ = _tmp10_;
		g_warning ("stats-manager.vala:529: Skip tracking %s: Missing category.", _tmp11_);
		_g_free0 (_tmp11_);
		_g_free0 (category);
		block54_data_unref (_data54_);
		_data54_ = NULL;
		return;
	}
	_tmp12_ = time_block_entry;
	if (_tmp12_ == NULL) {
		FtState _tmp13_;
		FtState _tmp14_;
		gchar* _tmp15_;
		gchar* _tmp16_;
		_tmp13_ = ft_time_block_get_state (time_block);
		_tmp14_ = _tmp13_;
		_tmp15_ = ft_state_to_string (_tmp14_);
		_tmp16_ = _tmp15_;
		g_warning ("stats-manager.vala:536: Skip tracking %s: Missing source entry.", _tmp16_);
		_g_free0 (_tmp16_);
		_g_free0 (category);
		block54_data_unref (_data54_);
		_data54_ = NULL;
		return;
	}
	ft_time_block_foreach_gap (time_block, ___lambda98__gfunc, _data54_);
	_tmp19_ = ft_schedulable_get_end_time ((FtSchedulable*) time_block);
	_tmp20_ = _tmp19_;
	if (ft_timestamp_is_defined (_tmp20_)) {
		gint64 _tmp21_;
		gint64 _tmp22_;
		_tmp21_ = ft_schedulable_get_end_time ((FtSchedulable*) time_block);
		_tmp22_ = _tmp21_;
		_tmp18_ = _tmp22_ > _data54_->timestamp;
	} else {
		_tmp18_ = FALSE;
	}
	if (_tmp18_) {
		_tmp17_ = ft_time_block_get_status (time_block) != FT_TIME_BLOCK_STATUS_IN_PROGRESS;
	} else {
		_tmp17_ = FALSE;
	}
	if (_tmp17_) {
		gint64 _tmp23_;
		gint64 _tmp24_;
		GDateTime* _tmp25_;
		FtStatsManagerSegment _tmp26_ = {0};
		_tmp23_ = ft_schedulable_get_end_time ((FtSchedulable*) time_block);
		_tmp24_ = _tmp23_;
		_tmp25_ = ft_stats_manager_transform_timestamp (self, _data54_->timestamp);
		memset (&_tmp26_, 0, sizeof (FtStatsManagerSegment));
		_tmp26_.timestamp = _data54_->timestamp;
		_tmp26_.duration = _tmp24_ - _data54_->timestamp;
		_g_date_time_unref0 (_tmp26_.datetime);
		_tmp26_.datetime = _tmp25_;
		_vala_array_add34 (&_data54_->segments, &_data54_->segments_length1, &_data54_->_segments_size_, &_tmp26_);
	}
	_tmp27_ = _data54_->segments;
	_tmp27__length1 = _data54_->segments_length1;
	_tmp28_ = (_tmp27_ != NULL) ? _vala_array_dup23 (_tmp27_, _tmp27__length1) : _tmp27_;
	_tmp28__length1 = _tmp27__length1;
	_tmp29_ = ft_schedulable_get_start_time ((FtSchedulable*) time_block);
	_tmp30_ = _tmp29_;
	_tmp31_ = ft_schedulable_get_duration ((FtSchedulable*) time_block);
	_tmp32_ = _tmp31_;
	_tmp34_ = ft_stats_manager_split (self, _tmp30_, _tmp32_, &_tmp33_);
	_tmp36_ = ft_stats_manager_intersect_segments (self, _tmp28_, (gint) _tmp28__length1, _tmp34_, (gint) _tmp33_, &_tmp35_);
	_data54_->segments = (_vala_FtStatsManagerSegment_array_free (_data54_->segments, _data54_->segments_length1), NULL);
	_data54_->segments = _tmp36_;
	_data54_->segments_length1 = _tmp35_;
	_data54_->_segments_size_ = _data54_->segments_length1;
	_tmp37_ = category;
	_tmp38_ = time_block_entry;
	_tmp39_ = ft_time_block_entry_get_id (_tmp38_);
	_tmp40_ = _tmp39_;
	_tmp41_ = _data54_->segments;
	_tmp41__length1 = _data54_->segments_length1;
	_tmp42_ = (_tmp41_ != NULL) ? _vala_array_dup24 (_tmp41_, _tmp41__length1) : _tmp41_;
	_tmp42__length1 = _tmp41__length1;
	ft_stats_manager_track_internal (self, _tmp37_, _tmp40_, _tmp42_, (gint) _tmp42__length1);
	_g_free0 (category);
	block54_data_unref (_data54_);
	_data54_ = NULL;
}

void
ft_stats_manager_track_gap (FtStatsManager* self,
                            FtGap* gap)
{
	FtTimeBlock* _tmp0_;
	FtTimeBlock* _tmp1_;
	FtGapEntry* gap_entry = NULL;
	FtGapEntry* _tmp2_;
	FtGapEntry* _tmp3_;
	gboolean _tmp4_ = FALSE;
	gint64 _tmp5_;
	gint64 _tmp6_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (gap != NULL);
	_tmp0_ = ft_gap_get_time_block (gap);
	_tmp1_ = _tmp0_;
	ft_stats_manager_try_save_time_block (self, _tmp1_);
	_tmp2_ = gap->entry;
	gap_entry = _tmp2_;
	_tmp3_ = gap_entry;
	if (_tmp3_ == NULL) {
		g_warning ("stats-manager.vala:579: Skipping tracking gap. Missing source entry.");
		return;
	}
	_tmp5_ = ft_schedulable_get_end_time ((FtSchedulable*) gap);
	_tmp6_ = _tmp5_;
	if (ft_timestamp_is_undefined (_tmp6_)) {
		_tmp4_ = TRUE;
	} else {
		FtTimeBlock* _tmp7_;
		FtTimeBlock* _tmp8_;
		_tmp7_ = ft_gap_get_time_block (gap);
		_tmp8_ = _tmp7_;
		_tmp4_ = ft_time_block_get_status (_tmp8_) == FT_TIME_BLOCK_STATUS_SCHEDULED;
	}
	if (_tmp4_) {
		return;
	}
	if (ft_gap_has_flag (gap, FT_GAP_FLAGS_INTERRUPTION)) {
		gint64 _tmp9_;
		gint64 _tmp10_;
		gint64 _tmp11_;
		gint64 _tmp12_;
		FtGapEntry* _tmp13_;
		gint64 _tmp14_;
		gint64 _tmp15_;
		_tmp9_ = ft_schedulable_get_start_time ((FtSchedulable*) gap);
		_tmp10_ = _tmp9_;
		_tmp11_ = ft_schedulable_get_duration ((FtSchedulable*) gap);
		_tmp12_ = _tmp11_;
		_tmp13_ = gap_entry;
		_tmp14_ = ft_gap_entry_get_id (_tmp13_);
		_tmp15_ = _tmp14_;
		ft_stats_manager_track (self, "interruption", _tmp10_, _tmp12_, _tmp15_);
	}
}

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

void
ft_stats_manager_flush (FtStatsManager* self,
                        GAsyncReadyCallback _callback_,
                        gpointer _user_data_)
{
	FtStatsManagerFlushData* _data_;
	FtStatsManager* _tmp0_;
	g_return_if_fail (self != NULL);
	_data_ = g_slice_new0 (FtStatsManagerFlushData);
	_data_->_async_result = g_task_new (G_OBJECT (self), NULL, _callback_, _user_data_);
	g_task_set_task_data (_data_->_async_result, _data_, ft_stats_manager_flush_data_free);
	_tmp0_ = _g_object_ref0 (self);
	_data_->self = _tmp0_;
	ft_stats_manager_flush_co (_data_);
}

void
ft_stats_manager_flush_finish (FtStatsManager* self,
                               GAsyncResult* _res_)
{
	FtStatsManagerFlushData* _data_;
	_data_ = g_task_propagate_pointer (G_TASK (_res_), NULL);
}

static void
ft_stats_manager_flush_ready (GObject* source_object,
                              GAsyncResult* _res_,
                              gpointer _user_data_)
{
	FtStatsManagerFlushData* _data_;
	_data_ = _user_data_;
	_data_->_source_object_ = source_object;
	_data_->_res_ = _res_;
	ft_stats_manager_flush_co (_data_);
}

static gboolean
_ft_stats_manager_flush_co_gsource_func (gpointer self)
{
	gboolean result;
	result = ft_stats_manager_flush_co (self);
	return result;
}

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

static gboolean
ft_stats_manager_flush_co (FtStatsManagerFlushData* _data_)
{
	switch (_data_->_state_) {
		case 0:
		goto _state_0;
		case 1:
		goto _state_1;
		case 2:
		goto _state_2;
		default:
		g_assert_not_reached ();
	}
	_state_0:
	_data_->_tmp0_ = _data_->self->priv->queue;
	_data_->_state_ = 1;
	ft_async_queue_wait (_data_->_tmp0_, ft_stats_manager_flush_ready, _data_);
	return FALSE;
	_state_1:
	ft_async_queue_wait_finish (_data_->_tmp0_, _data_->_res_);
	if (_data_->self->priv->is_processing) {
		_data_->_tmp1_ = ft_async_callback_new (_ft_stats_manager_flush_co_gsource_func, _data_, NULL);
		_vala_array_add35 (&_data_->self->priv->flush_callbacks, &_data_->self->priv->flush_callbacks_length1, &_data_->self->priv->_flush_callbacks_size_, _data_->_tmp1_);
		_data_->_state_ = 2;
		return FALSE;
		_state_2:
		;
	}
	g_task_return_pointer (_data_->_async_result, _data_, NULL);
	if (_data_->_state_ != 0) {
		while (!g_task_get_completed (_data_->_async_result)) {
			g_main_context_iteration (g_task_get_context (_data_->_async_result), TRUE);
		}
	}
	g_object_unref (_data_->_async_result);
	return FALSE;
}

GDateTime*
ft_stats_manager_get_midnight (FtStatsManager* self,
                               GDate* date)
{
	GTimeZone* timezone = NULL;
	FtTimezoneHistory* _tmp0_;
	GDate _tmp1_;
	GTimeZone* _tmp2_;
	GTimeZone* _tmp3_;
	GTimeZone* _tmp4_;
	gint midnight_hour = 0;
	GDateTime* midnight = NULL;
	GTimeZone* _tmp6_;
	GDateTime* _tmp7_;
	GDateTime* result;
	g_return_val_if_fail (self != NULL, NULL);
	g_return_val_if_fail (date != NULL, NULL);
	_tmp0_ = self->priv->timezone_history;
	_tmp1_ = *date;
	_tmp2_ = ft_timezone_history_search_by_date (_tmp0_, &_tmp1_, FT_STATS_MANAGER_MIDNIGHT_OFFSET);
	_tmp3_ = _g_time_zone_ref0 (_tmp2_);
	timezone = _tmp3_;
	_tmp4_ = timezone;
	if (_tmp4_ == NULL) {
		GTimeZone* _tmp5_;
		_tmp5_ = g_time_zone_new_local ();
		_g_time_zone_unref0 (timezone);
		timezone = _tmp5_;
	}
	midnight_hour = (gint) (FT_STATS_MANAGER_MIDNIGHT_OFFSET / FT_INTERVAL_HOUR);
	_tmp6_ = timezone;
	_tmp7_ = g_date_time_new (_tmp6_, (gint) g_date_get_year (date), (gint) g_date_get_month (date), (gint) g_date_get_day (date), midnight_hour, 0, (gdouble) 0);
	midnight = _tmp7_;
	result = midnight;
	_g_time_zone_unref0 (timezone);
	return result;
}

/**
         * Return todays date adjusted for virtual midnight.
         */
void
ft_stats_manager_get_today (FtStatsManager* self,
                            GDate* result)
{
	GDateTime* datetime = NULL;
	GDateTime* _tmp0_;
	GDate today = {0};
	GDate _tmp1_ = {0};
	g_return_if_fail (self != NULL);
	_tmp0_ = ft_stats_manager_transform_timestamp (self, ft_timestamp_from_now ());
	datetime = _tmp0_;
	memset (&today, 0, sizeof (GDate));
	ft_stats_manager_transform_datetime (self, datetime, &_tmp1_, NULL);
	today = _tmp1_;
	*result = today;
	_g_date_time_unref0 (datetime);
	return;
}

static void
ft_stats_manager_on_time_block_saved (FtStatsManager* self,
                                      FtTimeBlock* time_block,
                                      FtTimeBlockEntry* time_block_entry)
{
	g_return_if_fail (self != NULL);
	g_return_if_fail (time_block != NULL);
	g_return_if_fail (time_block_entry != NULL);
	ft_stats_manager_track_time_block (self, time_block);
}

static void
ft_stats_manager_on_gap_saved (FtStatsManager* self,
                               FtGap* gap,
                               FtGapEntry* gap_entry)
{
	g_return_if_fail (self != NULL);
	g_return_if_fail (gap != NULL);
	g_return_if_fail (gap_entry != NULL);
	ft_stats_manager_track_gap (self, gap);
}

static void
_ft_stats_manager_on_time_block_saved_ft_session_manager_time_block_saved (FtSessionManager* _sender,
                                                                           FtTimeBlock* time_block,
                                                                           FtTimeBlockEntry* time_block_entry,
                                                                           gpointer self)
{
	ft_stats_manager_on_time_block_saved ((FtStatsManager*) self, time_block, time_block_entry);
}

static void
_ft_stats_manager_on_gap_saved_ft_session_manager_gap_saved (FtSessionManager* _sender,
                                                             FtGap* gap,
                                                             FtGapEntry* gap_entry,
                                                             gpointer self)
{
	ft_stats_manager_on_gap_saved ((FtStatsManager*) self, gap, gap_entry);
}

static void
ft_stats_manager_real_dispose (GObject* base)
{
	FtStatsManager * self;
	FtSessionManager* _tmp0_;
	FtAsyncCallback** _tmp5_;
	self = (FtStatsManager*) base;
	_tmp0_ = self->priv->_session_manager;
	if (_tmp0_ != NULL) {
		FtSessionManager* _tmp1_;
		guint _tmp2_;
		FtSessionManager* _tmp3_;
		guint _tmp4_;
		_tmp1_ = self->priv->_session_manager;
		g_signal_parse_name ("time-block-saved", FT_TYPE_SESSION_MANAGER, &_tmp2_, NULL, FALSE);
		g_signal_handlers_disconnect_matched (_tmp1_, G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA, _tmp2_, 0, NULL, (GCallback) _ft_stats_manager_on_time_block_saved_ft_session_manager_time_block_saved, self);
		_tmp3_ = self->priv->_session_manager;
		g_signal_parse_name ("gap-saved", FT_TYPE_SESSION_MANAGER, &_tmp4_, NULL, FALSE);
		g_signal_handlers_disconnect_matched (_tmp3_, G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA, _tmp4_, 0, NULL, (GCallback) _ft_stats_manager_on_gap_saved_ft_session_manager_gap_saved, self);
		_g_object_unref0 (self->priv->_session_manager);
		self->priv->_session_manager = NULL;
	}
	_g_object_unref0 (self->priv->timezone_history);
	self->priv->timezone_history = NULL;
	_ft_async_queue_unref0 (self->priv->queue);
	self->priv->queue = NULL;
	_tmp5_ = g_new0 (FtAsyncCallback*, 0 + 1);
	self->priv->flush_callbacks = (_vala_array_free (self->priv->flush_callbacks, self->priv->flush_callbacks_length1, (GDestroyNotify) ft_async_callback_free), NULL);
	self->priv->flush_callbacks = _tmp5_;
	self->priv->flush_callbacks_length1 = 0;
	self->priv->_flush_callbacks_size_ = self->priv->flush_callbacks_length1;
	G_OBJECT_CLASS (ft_stats_manager_parent_class)->dispose (G_TYPE_CHECK_INSTANCE_CAST (self, G_TYPE_OBJECT, GObject));
}

FtSessionManager*
ft_stats_manager_get_session_manager (FtStatsManager* self)
{
	FtSessionManager* result;
	FtSessionManager* _tmp0_;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->_session_manager;
	result = _tmp0_;
	return result;
}

static void
ft_stats_manager_set_session_manager (FtStatsManager* self,
                                      FtSessionManager* value)
{
	FtSessionManager* _tmp0_;
	FtSessionManager* _tmp1_;
	FtSessionManager* _tmp2_;
	g_return_if_fail (self != NULL);
	_tmp0_ = _g_object_ref0 (value);
	_g_object_unref0 (self->priv->_session_manager);
	self->priv->_session_manager = _tmp0_;
	_tmp1_ = self->priv->_session_manager;
	g_signal_connect_object (_tmp1_, "time-block-saved", (GCallback) _ft_stats_manager_on_time_block_saved_ft_session_manager_time_block_saved, self, 0);
	_tmp2_ = self->priv->_session_manager;
	g_signal_connect_object (_tmp2_, "gap-saved", (GCallback) _ft_stats_manager_on_gap_saved_ft_session_manager_gap_saved, self, 0);
	g_object_notify_by_pspec ((GObject *) self, ft_stats_manager_properties[FT_STATS_MANAGER_SESSION_MANAGER_PROPERTY]);
}

static inline gboolean
ft_stats_manager_segment_is_valid (FtStatsManagerSegment *self)
{
	gboolean _tmp0_ = FALSE;
	gboolean _tmp1_ = FALSE;
	gboolean result;
	if (ft_timestamp_is_defined ((*self).timestamp)) {
		GDateTime* _tmp2_;
		_tmp2_ = (*self).datetime;
		_tmp1_ = _tmp2_ != NULL;
	} else {
		_tmp1_ = FALSE;
	}
	if (_tmp1_) {
		_tmp0_ = (*self).duration > ((gint64) 0);
	} else {
		_tmp0_ = FALSE;
	}
	result = _tmp0_;
	return result;
}

static void
ft_stats_manager_segment_copy (const FtStatsManagerSegment* self,
                               FtStatsManagerSegment* dest)
{
	GDateTime* _tmp0_;
	GDateTime* _tmp1_;
	(*dest).timestamp = (*self).timestamp;
	(*dest).duration = (*self).duration;
	_tmp0_ = (*self).datetime;
	_tmp1_ = _g_date_time_ref0 (_tmp0_);
	_g_date_time_unref0 ((*dest).datetime);
	(*dest).datetime = _tmp1_;
}

static void
ft_stats_manager_segment_destroy (FtStatsManagerSegment* self)
{
	_g_date_time_unref0 ((*self).datetime);
}

static FtStatsManagerSegment*
ft_stats_manager_segment_dup (const FtStatsManagerSegment* self)
{
	FtStatsManagerSegment* dup;
	dup = g_new0 (FtStatsManagerSegment, 1);
	ft_stats_manager_segment_copy (self, dup);
	return dup;
}

static void
ft_stats_manager_segment_free (FtStatsManagerSegment* self)
{
	ft_stats_manager_segment_destroy (self);
	g_free (self);
}

static GType
ft_stats_manager_segment_get_type_once (void)
{
	GType ft_stats_manager_segment_type_id;
	ft_stats_manager_segment_type_id = g_boxed_type_register_static ("FtStatsManagerSegment", (GBoxedCopyFunc) ft_stats_manager_segment_dup, (GBoxedFreeFunc) ft_stats_manager_segment_free);
	return ft_stats_manager_segment_type_id;
}

static GType
ft_stats_manager_segment_get_type (void)
{
	static volatile gsize ft_stats_manager_segment_type_id__once = 0;
	if (g_once_init_enter (&ft_stats_manager_segment_type_id__once)) {
		GType ft_stats_manager_segment_type_id;
		ft_stats_manager_segment_type_id = ft_stats_manager_segment_get_type_once ();
		g_once_init_leave (&ft_stats_manager_segment_type_id__once, ft_stats_manager_segment_type_id);
	}
	return ft_stats_manager_segment_type_id__once;
}

static FtStatsManagerSegment*
_vala_array_dup25 (FtStatsManagerSegment* self,
                   gssize length)
{
	if (length > 0) {
		FtStatsManagerSegment* result;
		gssize i;
		result = g_new0 (FtStatsManagerSegment, length);
		for (i = 0; i < length; i++) {
			FtStatsManagerSegment _tmp0_;
			FtStatsManagerSegment _tmp1_ = {0};
			_tmp0_ = self[i];
			ft_stats_manager_segment_copy (&_tmp0_, &_tmp1_);
			result[i] = _tmp1_;
		}
		return result;
	}
	return NULL;
}

static void
ft_stats_manager_item_copy (const FtStatsManagerItem* self,
                            FtStatsManagerItem* dest)
{
	const gchar* _tmp0_;
	gchar* _tmp1_;
	FtStatsManagerSegment* _tmp2_;
	gint _tmp2__length1;
	FtStatsManagerSegment* _tmp3_;
	gint _tmp3__length1;
	_tmp0_ = (*self).category;
	_tmp1_ = g_strdup (_tmp0_);
	_g_free0 ((*dest).category);
	(*dest).category = _tmp1_;
	(*dest).source_id = (*self).source_id;
	_tmp2_ = (*self).segments;
	_tmp2__length1 = (*self).segments_length1;
	_tmp3_ = (_tmp2_ != NULL) ? _vala_array_dup25 (_tmp2_, _tmp2__length1) : _tmp2_;
	_tmp3__length1 = _tmp2__length1;
	(*dest).segments = (_vala_FtStatsManagerSegment_array_free ((*dest).segments, (*dest).segments_length1), NULL);
	(*dest).segments = _tmp3_;
	(*dest).segments_length1 = _tmp3__length1;
	(*dest)._segments_size_ = (*dest).segments_length1;
}

static void
ft_stats_manager_item_destroy (FtStatsManagerItem* self)
{
	_g_free0 ((*self).category);
	(*self).segments = (_vala_FtStatsManagerSegment_array_free ((*self).segments, (*self).segments_length1), NULL);
}

static FtStatsManagerItem*
ft_stats_manager_item_dup (const FtStatsManagerItem* self)
{
	FtStatsManagerItem* dup;
	dup = g_new0 (FtStatsManagerItem, 1);
	ft_stats_manager_item_copy (self, dup);
	return dup;
}

static void
ft_stats_manager_item_free (FtStatsManagerItem* self)
{
	ft_stats_manager_item_destroy (self);
	g_free (self);
}

static GType
ft_stats_manager_item_get_type_once (void)
{
	GType ft_stats_manager_item_type_id;
	ft_stats_manager_item_type_id = g_boxed_type_register_static ("FtStatsManagerItem", (GBoxedCopyFunc) ft_stats_manager_item_dup, (GBoxedFreeFunc) ft_stats_manager_item_free);
	return ft_stats_manager_item_type_id;
}

static GType
ft_stats_manager_item_get_type (void)
{
	static volatile gsize ft_stats_manager_item_type_id__once = 0;
	if (g_once_init_enter (&ft_stats_manager_item_type_id__once)) {
		GType ft_stats_manager_item_type_id;
		ft_stats_manager_item_type_id = ft_stats_manager_item_get_type_once ();
		g_once_init_leave (&ft_stats_manager_item_type_id__once, ft_stats_manager_item_type_id);
	}
	return ft_stats_manager_item_type_id__once;
}

static GObject *
ft_stats_manager_constructor (GType type,
                              guint n_construct_properties,
                              GObjectConstructParam * construct_properties)
{
	GObject * obj;
	GObjectClass * parent_class;
	static GWeakRef FtStatsManager_singleton__ref;
	static GMutex FtStatsManager_singleton__lock;
	FtStatsManager * self;
	FtTimezoneHistory* _tmp0_;
	FtAsyncQueue* _tmp1_;
	FtAsyncCallback** _tmp2_;
	g_mutex_lock (&FtStatsManager_singleton__lock);
	obj = g_weak_ref_get (&FtStatsManager_singleton__ref);
	if (obj != NULL) {
		g_mutex_unlock (&FtStatsManager_singleton__lock);
		return obj;
	}
	parent_class = G_OBJECT_CLASS (ft_stats_manager_parent_class);
	obj = parent_class->constructor (type, n_construct_properties, construct_properties);
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, FT_TYPE_STATS_MANAGER, FtStatsManager);
	_tmp0_ = ft_timezone_history_new ();
	_g_object_unref0 (self->priv->timezone_history);
	self->priv->timezone_history = _tmp0_;
	_tmp1_ = ft_async_queue_new (FT_STATS_MANAGER_TYPE_ITEM, (GBoxedCopyFunc) ft_stats_manager_item_dup, (GDestroyNotify) ft_stats_manager_item_free);
	_ft_async_queue_unref0 (self->priv->queue);
	self->priv->queue = _tmp1_;
	_tmp2_ = g_new0 (FtAsyncCallback*, 0 + 1);
	self->priv->flush_callbacks = (_vala_array_free (self->priv->flush_callbacks, self->priv->flush_callbacks_length1, (GDestroyNotify) ft_async_callback_free), NULL);
	self->priv->flush_callbacks = _tmp2_;
	self->priv->flush_callbacks_length1 = 0;
	self->priv->_flush_callbacks_size_ = self->priv->flush_callbacks_length1;
	g_weak_ref_set (&FtStatsManager_singleton__ref, obj);
	g_mutex_unlock (&FtStatsManager_singleton__lock);
	return obj;
}

static void
ft_stats_manager_class_init (FtStatsManagerClass * klass,
                             gpointer klass_data)
{
	ft_stats_manager_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &FtStatsManager_private_offset);
	((GObjectClass *) klass)->dispose = (void (*) (GObject*)) ft_stats_manager_real_dispose;
	G_OBJECT_CLASS (klass)->get_property = _vala_ft_stats_manager_get_property;
	G_OBJECT_CLASS (klass)->set_property = _vala_ft_stats_manager_set_property;
	G_OBJECT_CLASS (klass)->constructor = ft_stats_manager_constructor;
	G_OBJECT_CLASS (klass)->finalize = ft_stats_manager_finalize;
	g_object_class_install_property (G_OBJECT_CLASS (klass), FT_STATS_MANAGER_SESSION_MANAGER_PROPERTY, ft_stats_manager_properties[FT_STATS_MANAGER_SESSION_MANAGER_PROPERTY] = g_param_spec_object ("session-manager", "session-manager", "session-manager", FT_TYPE_SESSION_MANAGER, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
	ft_stats_manager_signals[FT_STATS_MANAGER_ENTRY_SAVED_SIGNAL] = g_signal_new ("entry-saved", FT_TYPE_STATS_MANAGER, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1, FT_TYPE_STATS_ENTRY);
	ft_stats_manager_signals[FT_STATS_MANAGER_ENTRY_DELETED_SIGNAL] = g_signal_new ("entry-deleted", FT_TYPE_STATS_MANAGER, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1, FT_TYPE_STATS_ENTRY);
}

static void
ft_stats_manager_instance_init (FtStatsManager * self,
                                gpointer klass)
{
	self->priv = ft_stats_manager_get_instance_private (self);
	self->priv->_session_manager = NULL;
	self->priv->timezone_history = NULL;
	self->priv->queue = NULL;
	self->priv->is_processing = FALSE;
}

static void
ft_stats_manager_finalize (GObject * obj)
{
	FtStatsManager * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, FT_TYPE_STATS_MANAGER, FtStatsManager);
	_g_object_unref0 (self->priv->_session_manager);
	_g_object_unref0 (self->priv->timezone_history);
	_ft_async_queue_unref0 (self->priv->queue);
	self->priv->flush_callbacks = (_vala_array_free (self->priv->flush_callbacks, self->priv->flush_callbacks_length1, (GDestroyNotify) ft_async_callback_free), NULL);
	G_OBJECT_CLASS (ft_stats_manager_parent_class)->finalize (obj);
}

/**
     * Class responsible for time-tracking and collecting stats
     */
static GType
ft_stats_manager_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (FtStatsManagerClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) ft_stats_manager_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (FtStatsManager), 0, (GInstanceInitFunc) ft_stats_manager_instance_init, NULL };
	GType ft_stats_manager_type_id;
	ft_stats_manager_type_id = g_type_register_static (G_TYPE_OBJECT, "FtStatsManager", &g_define_type_info, 0);
	FtStatsManager_private_offset = g_type_add_instance_private (ft_stats_manager_type_id, sizeof (FtStatsManagerPrivate));
	return ft_stats_manager_type_id;
}

GType
ft_stats_manager_get_type (void)
{
	static volatile gsize ft_stats_manager_type_id__once = 0;
	if (g_once_init_enter (&ft_stats_manager_type_id__once)) {
		GType ft_stats_manager_type_id;
		ft_stats_manager_type_id = ft_stats_manager_get_type_once ();
		g_once_init_leave (&ft_stats_manager_type_id__once, ft_stats_manager_type_id);
	}
	return ft_stats_manager_type_id__once;
}

static void
_vala_ft_stats_manager_get_property (GObject * object,
                                     guint property_id,
                                     GValue * value,
                                     GParamSpec * pspec)
{
	FtStatsManager * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, FT_TYPE_STATS_MANAGER, FtStatsManager);
	switch (property_id) {
		case FT_STATS_MANAGER_SESSION_MANAGER_PROPERTY:
		g_value_set_object (value, ft_stats_manager_get_session_manager (self));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

static void
_vala_ft_stats_manager_set_property (GObject * object,
                                     guint property_id,
                                     const GValue * value,
                                     GParamSpec * pspec)
{
	FtStatsManager * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, FT_TYPE_STATS_MANAGER, FtStatsManager);
	switch (property_id) {
		case FT_STATS_MANAGER_SESSION_MANAGER_PROPERTY:
		ft_stats_manager_set_session_manager (self, g_value_get_object (value));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

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

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

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;
}

