static gboolean
_set_metadata (gpointer key, GValue *data, RBMetaData *metadata)
{
	RBMetaDataField field = GPOINTER_TO_INT (key);
	rb_metadata_set (metadata, field, data);
	return TRUE;
}
static void
rb_metadata_dbus_save (GVariant *parameters,
		       GDBusMethodInvocation *invocation,
		       ServiceData *svc)
{
	const char *uri;
	GError *error = NULL;
	GVariantIter *metadata;
	RBMetaDataField key;
	GVariant *value;

	g_variant_get (parameters, "(&sa{iv})", &uri, &metadata);

	/* pass metadata to real metadata instance */
	rb_metadata_reset (svc->metadata);
	while (g_variant_iter_next (metadata, "{iv}", &key, &value)) {
		GValue val = {0,};

		switch (rb_metadata_get_field_type (key)) {
		case G_TYPE_STRING:
			g_value_init (&val, G_TYPE_STRING);
			g_value_set_string (&val, g_variant_get_string (value, NULL));
			break;
		case G_TYPE_ULONG:
			g_value_init (&val, G_TYPE_ULONG);
			g_value_set_ulong (&val, g_variant_get_uint32 (value));
			break;
		case G_TYPE_DOUBLE:
			g_value_init (&val, G_TYPE_DOUBLE);
			g_value_set_double (&val, g_variant_get_double (value));
			break;
		default:
			g_assert_not_reached ();
			break;
		}
		rb_metadata_set (svc->metadata, key, &val);
		g_variant_unref (value);
		g_value_unset (&val);
	}

	rb_metadata_save (svc->metadata, uri, &error);
	g_dbus_method_invocation_return_value (invocation,
					       g_variant_new ("(bis)",
							      (error == NULL),
							      (error != NULL ? error->code : 0),
							      (error != NULL ? error->message : "")));
}