void
camel_gw_summary_add_offline (CamelFolderSummary *summary, const char *uid, CamelMimeMessage *message, const CamelMessageInfo *info)
{
	CamelGroupwiseMessageInfo *mi ;
	const CamelFlag *flag ;
	const CamelTag *tag ;

	/* Create summary entry */
	mi = (CamelGroupwiseMessageInfo *)camel_folder_summary_info_new_from_message (summary, message) ;

	/* Copy flags 'n' tags */
	mi->info.flags = camel_message_info_flags(info) ;

	flag = camel_message_info_user_flags(info) ;
	while (flag) {
		camel_message_info_set_user_flag((CamelMessageInfo *)mi, flag->name, TRUE);
		flag = flag->next;
	}
	tag = camel_message_info_user_tags(info);
	while (tag) {
		camel_message_info_set_user_tag((CamelMessageInfo *)mi, tag->name, tag->value);
		tag = tag->next;
	}

	mi->info.size = camel_message_info_size(info);
	mi->info.uid = g_strdup (uid);

	camel_folder_summary_add (summary, (CamelMessageInfo *)mi);

}
static gboolean
update_cache (CamelGroupwiseJournal *groupwise_journal, CamelMimeMessage *message,
	      const CamelMessageInfo *mi, char **updated_uid, CamelException *ex)
{
	CamelOfflineJournal *journal = (CamelOfflineJournal *) groupwise_journal;
	CamelGroupwiseFolder *groupwise_folder = (CamelGroupwiseFolder *) journal->folder;
	CamelFolder *folder = (CamelFolder *) journal->folder;
	CamelMessageInfo *info;
	CamelStream *cache;
	guint32 nextuid;
	char *uid;

	if (groupwise_folder->cache == NULL) {
		camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM,
				     _("Cannot append message in offline mode: cache unavailable"));
		return FALSE;
	}

	nextuid = camel_folder_summary_next_uid (folder->summary);
	uid = g_strdup_printf ("-%u", nextuid);

	if (!(cache = camel_data_cache_add (groupwise_folder->cache, "cache", uid, ex))) {
		folder->summary->nextuid--;
		g_free (uid);
		return FALSE;
	}

	if (camel_data_wrapper_write_to_stream ((CamelDataWrapper *) message, cache) == -1
	    || camel_stream_flush (cache) == -1) {
		camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
				      _("Cannot append message in offline mode: %s"),
				      g_strerror (errno));
		camel_data_cache_remove (groupwise_folder->cache, "cache", uid, NULL);
		folder->summary->nextuid--;
		camel_object_unref (cache);
		g_free (uid);
		return FALSE;
	}

	camel_object_unref (cache);

	info = camel_folder_summary_info_new_from_message (folder->summary, message);
	g_free(info->uid);
	info->uid = g_strdup (uid);

	gw_message_info_dup_to ((CamelMessageInfoBase *) info, (CamelMessageInfoBase *) mi);

	camel_folder_summary_add (folder->summary, info);

	if (updated_uid)
		*updated_uid = g_strdup (uid);

	g_free (uid);

	return TRUE;
}
static gint
exchange_entry_play_append (CamelOfflineJournal *journal,
                            CamelExchangeJournalEntry *entry,
                            GCancellable *cancellable,
                            GError **error)
{
	CamelExchangeFolder *exchange_folder = (CamelExchangeFolder *) journal->folder;
	CamelFolder *folder = journal->folder;
	CamelMimeMessage *message;
	CamelMessageInfo *info, *real;
	CamelStream *stream;
	gchar *uid = NULL;

	/* if the message isn't in the cache, the user went behind our backs so "not our problem" */
	if (!exchange_folder->cache || !(stream = camel_data_cache_get (exchange_folder->cache, "cache", entry->uid, NULL)))
		goto done;

	message = camel_mime_message_new ();
	if (!camel_data_wrapper_construct_from_stream_sync (
		(CamelDataWrapper *) message, stream, cancellable, NULL)) {
		g_object_unref (message);
		g_object_unref (stream);
		goto done;
	}

	g_object_unref (stream);

	if (!(info = camel_folder_summary_get (folder->summary, entry->uid))) {
		/* Should have never happened, but create a new info to avoid further crashes */
		info = camel_message_info_new (NULL);
	}

	if (!camel_folder_append_message_sync (
		folder, message, info, &uid, cancellable, error))
		return -1;

	real = camel_folder_summary_info_new_from_message (folder->summary, message, NULL);
	g_object_unref (message);

	if (uid != NULL && real) {
		real->uid = camel_pstring_strdup (uid);
		exchange_message_info_dup_to ((CamelMessageInfoBase *) real, (CamelMessageInfoBase *) info);
		camel_folder_summary_add (folder->summary, real);
		/* FIXME: should a folder_changed event be triggered? */
	}
	camel_message_info_free (info);
	g_free (uid);

 done:

	camel_exchange_folder_remove_message (exchange_folder, entry->uid);

	return 0;
}
static gint
exchange_entry_play_transfer (CamelOfflineJournal *journal,
                              CamelExchangeJournalEntry *entry,
                              GCancellable *cancellable,
                              GError **error)
{
	CamelExchangeFolder *exchange_folder = (CamelExchangeFolder *) journal->folder;
	CamelFolder *folder = journal->folder;
	CamelMessageInfo *info, *real;
	GPtrArray *xuids, *uids;
	CamelFolder *src;
	CamelExchangeStore *store;
	CamelStream *stream;
	CamelMimeMessage *message;
	CamelStore *parent_store;

	if (!exchange_folder->cache || !(stream = camel_data_cache_get (exchange_folder->cache, "cache", entry->uid, NULL)))
		goto done;

	message = camel_mime_message_new ();
	if (!camel_data_wrapper_construct_from_stream_sync (
		(CamelDataWrapper *) message, stream, cancellable, NULL)) {
		g_object_unref (message);
		g_object_unref (stream);
		goto done;
	}

	g_object_unref (stream);

	if (!(info = camel_folder_summary_get (folder->summary, entry->uid))) {
		/* Note: this should never happen, but rather than crash lets make a new info */
		info = camel_message_info_new (NULL);
	}

	if (!entry->folder_name) {
		g_set_error (
			error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
			_("No folder name found"));
		goto exception;
	}

	parent_store = camel_folder_get_parent_store (folder);
	store = CAMEL_EXCHANGE_STORE (parent_store);

	g_mutex_lock (store->folders_lock);
	src = (CamelFolder *) g_hash_table_lookup (store->folders, entry->folder_name);
	g_mutex_unlock (store->folders_lock);

	if (src) {
		gboolean success;
		uids = g_ptr_array_sized_new (1);
		g_ptr_array_add (uids, entry->original_uid);

		success = camel_folder_transfer_messages_to_sync (
			src, uids, folder, entry->delete_original,
			&xuids, cancellable, error);
		if (!success)
			goto exception;

		real = camel_folder_summary_info_new_from_message (
			folder->summary, message, NULL);
		g_object_unref (message);
		real->uid = camel_pstring_strdup (
			(gchar *) xuids->pdata[0]);
		/* Transfer flags */
		exchange_message_info_dup_to (
			(CamelMessageInfoBase *) real,
			(CamelMessageInfoBase *) info);
		camel_folder_summary_add (folder->summary, real);
		/* FIXME: should a folder_changed event be triggered? */

		g_ptr_array_free (xuids, TRUE);
		g_ptr_array_free (uids, TRUE);
		/* g_object_unref (src); FIXME: should we? */

	} else {
		g_set_error (
			error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
			_("Folder doesn't exist"));
		goto exception;
	}

	camel_message_info_free (info);
done:
	camel_exchange_folder_remove_message (exchange_folder, entry->uid);

	return 0;

exception:

	camel_message_info_free (info);

	return -1;
}