[libgdata] [gcontact] Add GDataGContactExternalID



commit 4dd2c49b2039d8d6153cbe5563a531e6c55aa77f
Author: Philip Withnall <philip tecnocode co uk>
Date:   Tue Apr 6 18:04:08 2010 +0100

    [gcontact] Add GDataGContactExternalID
    
    Helps: bgo#613551

 Makefile.am                                      |    2 +
 docs/reference/gdata-docs.xml                    |    1 +
 docs/reference/gdata-sections.txt                |   32 ++
 gdata/gcontact/gdata-gcontact-external-id.c      |  421 ++++++++++++++++++++++
 gdata/gcontact/gdata-gcontact-external-id.h      |  128 +++++++
 gdata/gdata.h                                    |    1 +
 gdata/gdata.symbols                              |   12 +
 gdata/services/contacts/gdata-contacts-contact.c |   67 ++++-
 gdata/services/contacts/gdata-contacts-contact.h |    5 +
 gdata/tests/contacts.c                           |   27 ++
 gdata/tests/general.c                            |   87 +++++
 11 files changed, 781 insertions(+), 2 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index 01db9e6..07fe640 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -192,6 +192,7 @@ gdatagcontactincludedir = $(gdataincludedir)/gcontact
 gdatagcontactinclude_HEADERS = \
 	gdata/gcontact/gdata-gcontact-calendar.h	\
 	gdata/gcontact/gdata-gcontact-event.h		\
+	gdata/gcontact/gdata-gcontact-external-id.h	\
 	gdata/gcontact/gdata-gcontact-jot.h		\
 	gdata/gcontact/gdata-gcontact-relation.h	\
 	gdata/gcontact/gdata-gcontact-website.h
@@ -299,6 +300,7 @@ gdata_libgdata_la_SOURCES = \
 	\
 	gdata/gcontact/gdata-gcontact-calendar.c	\
 	gdata/gcontact/gdata-gcontact-event.c		\
+	gdata/gcontact/gdata-gcontact-external-id.c	\
 	gdata/gcontact/gdata-gcontact-jot.c		\
 	gdata/gcontact/gdata-gcontact-relation.c	\
 	gdata/gcontact/gdata-gcontact-website.c		\
diff --git a/docs/reference/gdata-docs.xml b/docs/reference/gdata-docs.xml
index 8dddbe4..8a0b110 100644
--- a/docs/reference/gdata-docs.xml
+++ b/docs/reference/gdata-docs.xml
@@ -70,6 +70,7 @@
 			<title>GContact API</title>
 			<xi:include href="xml/gdata-gcontact-calendar.xml"/>
 			<xi:include href="xml/gdata-gcontact-event.xml"/>
+			<xi:include href="xml/gdata-gcontact-external-id.xml"/>
 			<xi:include href="xml/gdata-gcontact-jot.xml"/>
 			<xi:include href="xml/gdata-gcontact-relation.xml"/>
 			<xi:include href="xml/gdata-gcontact-website.xml"/>
diff --git a/docs/reference/gdata-sections.txt b/docs/reference/gdata-sections.txt
index 910a9b9..86fb9cc 100644
--- a/docs/reference/gdata-sections.txt
+++ b/docs/reference/gdata-sections.txt
@@ -389,6 +389,9 @@ gdata_contacts_contact_add_calendar
 gdata_contacts_contact_get_calendars
 gdata_contacts_contact_get_primary_calendar
 gdata_contacts_contact_remove_all_calendars
+gdata_contacts_contact_add_external_id
+gdata_contacts_contact_get_external_ids
+gdata_contacts_contact_remove_all_external_ids
 gdata_contacts_contact_get_groups
 gdata_contacts_contact_add_group
 gdata_contacts_contact_remove_group
@@ -1935,3 +1938,32 @@ GDATA_TYPE_GCONTACT_CALENDAR
 <SUBSECTION Private>
 GDataGContactCalendarPrivate
 </SECTION>
+
+<SECTION>
+<FILE>gdata-gcontact-external-id</FILE>
+<TITLE>GDataGContactExternalID</TITLE>
+GDATA_GCONTACT_EXTERNAL_ID_ACCOUNT
+GDATA_GCONTACT_EXTERNAL_ID_CUSTOMER
+GDATA_GCONTACT_EXTERNAL_ID_NETWORK
+GDATA_GCONTACT_EXTERNAL_ID_ORGANIZATION
+GDataGContactExternalID
+GDataGContactExternalIDClass
+gdata_gcontact_external_id_new
+gdata_gcontact_external_id_compare
+gdata_gcontact_external_id_get_value
+gdata_gcontact_external_id_set_value
+gdata_gcontact_external_id_get_relation_type
+gdata_gcontact_external_id_set_relation_type
+gdata_gcontact_external_id_get_label
+gdata_gcontact_external_id_set_label
+<SUBSECTION Standard>
+gdata_gcontact_external_id_get_type
+GDATA_GCONTACT_EXTERNAL_ID
+GDATA_GCONTACT_EXTERNAL_ID_CLASS
+GDATA_GCONTACT_EXTERNAL_ID_GET_CLASS
+GDATA_IS_GCONTACT_EXTERNAL_ID
+GDATA_IS_GCONTACT_EXTERNAL_ID_CLASS
+GDATA_TYPE_GCONTACT_EXTERNAL_ID
+<SUBSECTION Private>
+GDataGContactExternalIDPrivate
+</SECTION>
diff --git a/gdata/gcontact/gdata-gcontact-external-id.c b/gdata/gcontact/gdata-gcontact-external-id.c
new file mode 100644
index 0000000..274b30c
--- /dev/null
+++ b/gdata/gcontact/gdata-gcontact-external-id.c
@@ -0,0 +1,421 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/*
+ * GData Client
+ * Copyright (C) Philip Withnall 2010 <philip tecnocode co uk>
+ *
+ * GData Client is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * GData Client is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GData Client.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * SECTION:gdata-gcontact-external-id
+ * @short_description: gContact externalId element
+ * @stability: Unstable
+ * @include: gdata/gcontact/gdata-gcontact-external-id.h
+ *
+ * #GDataGContactExternalID represents an "externalId" element from the
+ * <ulink type="http" url="http://code.google.com/apis/contacts/docs/3.0/reference.html#gcExternalId";>gContact specification</ulink>.
+ *
+ * Since: 0.7.0
+ **/
+
+#include <glib.h>
+#include <libxml/parser.h>
+
+#include "gdata-gcontact-external-id.h"
+#include "gdata-parsable.h"
+#include "gdata-parser.h"
+
+static void gdata_gcontact_external_id_finalize (GObject *object);
+static void gdata_gcontact_external_id_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec);
+static void gdata_gcontact_external_id_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec);
+static gboolean pre_parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *root_node, gpointer user_data, GError **error);
+static void pre_get_xml (GDataParsable *parsable, GString *xml_string);
+static void get_namespaces (GDataParsable *parsable, GHashTable *namespaces);
+
+struct _GDataGContactExternalIDPrivate {
+	gchar *value;
+	gchar *relation_type;
+	gchar *label;
+};
+
+enum {
+	PROP_VALUE = 1,
+	PROP_RELATION_TYPE,
+	PROP_LABEL
+};
+
+G_DEFINE_TYPE (GDataGContactExternalID, gdata_gcontact_external_id, GDATA_TYPE_PARSABLE)
+
+static void
+gdata_gcontact_external_id_class_init (GDataGContactExternalIDClass *klass)
+{
+	GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+	GDataParsableClass *parsable_class = GDATA_PARSABLE_CLASS (klass);
+
+	g_type_class_add_private (klass, sizeof (GDataGContactExternalIDPrivate));
+
+	gobject_class->get_property = gdata_gcontact_external_id_get_property;
+	gobject_class->set_property = gdata_gcontact_external_id_set_property;
+	gobject_class->finalize = gdata_gcontact_external_id_finalize;
+
+	parsable_class->pre_parse_xml = pre_parse_xml;
+	parsable_class->pre_get_xml = pre_get_xml;
+	parsable_class->get_namespaces = get_namespaces;
+	parsable_class->element_name = "externalId";
+	parsable_class->element_namespace = "gContact";
+
+	/**
+	 * GDataGContactExternalID:value:
+	 *
+	 * The value of the external ID.
+	 *
+	 * For more information, see the
+	 * <ulink type="http" url="http://code.google.com/apis/contacts/docs/3.0/reference.html#gcExternalId";>gContact specification</ulink>.
+	 *
+	 * Since: 0.7.0
+	 **/
+	g_object_class_install_property (gobject_class, PROP_VALUE,
+				g_param_spec_string ("value",
+					"Value", "The value of the external ID.",
+					NULL,
+					G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+	/**
+	 * GDataGContactExternalID:relation-type:
+	 *
+	 * A programmatic value that identifies the type of external ID. It is mutually exclusive with #GDataGContactExternalID:label.
+	 * Examples are %GDATA_GCONTACT_EXTERNAL_ID_NETWORK or %GDATA_GCONTACT_EXTERNAL_ID_ACCOUNT.
+	 *
+	 * For more information, see the
+	 * <ulink type="http" url="http://code.google.com/apis/contacts/docs/3.0/reference.html#gcExternalId";>gContact specification</ulink>.
+	 *
+	 * Since: 0.7.0
+	 **/
+	g_object_class_install_property (gobject_class, PROP_RELATION_TYPE,
+				g_param_spec_string ("relation-type",
+					"Relation type", "A programmatic value that identifies the type of external ID.",
+					NULL,
+					G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+	/**
+	 * GDataGContactExternalID:label:
+	 *
+	 * A free-form string that identifies the type of external ID. It is mutually exclusive with #GDataGContactExternalID:relation-type.
+	 *
+	 * For more information, see the
+	 * <ulink type="http" url="http://code.google.com/apis/contacts/docs/3.0/reference.html#gcExternalId";>gContact specification</ulink>.
+	 *
+	 * Since: 0.7.0
+	 **/
+	g_object_class_install_property (gobject_class, PROP_LABEL,
+				g_param_spec_string ("label",
+					"Label", "A free-form string that identifies the type of external ID.",
+					NULL,
+					G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+}
+
+static void
+gdata_gcontact_external_id_init (GDataGContactExternalID *self)
+{
+	self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GDATA_TYPE_GCONTACT_EXTERNAL_ID, GDataGContactExternalIDPrivate);
+}
+
+static void
+gdata_gcontact_external_id_finalize (GObject *object)
+{
+	GDataGContactExternalIDPrivate *priv = GDATA_GCONTACT_EXTERNAL_ID (object)->priv;
+
+	g_free (priv->value);
+	g_free (priv->relation_type);
+	g_free (priv->label);
+
+	/* Chain up to the parent class */
+	G_OBJECT_CLASS (gdata_gcontact_external_id_parent_class)->finalize (object);
+}
+
+static void
+gdata_gcontact_external_id_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
+{
+	GDataGContactExternalIDPrivate *priv = GDATA_GCONTACT_EXTERNAL_ID (object)->priv;
+
+	switch (property_id) {
+		case PROP_VALUE:
+			g_value_set_string (value, priv->value);
+			break;
+		case PROP_RELATION_TYPE:
+			g_value_set_string (value, priv->relation_type);
+			break;
+		case PROP_LABEL:
+			g_value_set_string (value, priv->label);
+			break;
+		default:
+			/* We don't have any other property... */
+			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+			break;
+	}
+}
+
+static void
+gdata_gcontact_external_id_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
+{
+	GDataGContactExternalID *self = GDATA_GCONTACT_EXTERNAL_ID (object);
+
+	switch (property_id) {
+		case PROP_VALUE:
+			gdata_gcontact_external_id_set_value (self, g_value_get_string (value));
+			break;
+		case PROP_RELATION_TYPE:
+			gdata_gcontact_external_id_set_relation_type (self, g_value_get_string (value));
+			break;
+		case PROP_LABEL:
+			gdata_gcontact_external_id_set_label (self, g_value_get_string (value));
+			break;
+		default:
+			/* We don't have any other property... */
+			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+			break;
+	}
+}
+
+static gboolean
+pre_parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *root_node, gpointer user_data, GError **error)
+{
+	xmlChar *value, *rel, *label;
+	GDataGContactExternalIDPrivate *priv = GDATA_GCONTACT_EXTERNAL_ID (parsable)->priv;
+
+	value = xmlGetProp (root_node, (xmlChar*) "value");
+	if (value == NULL) {
+		xmlFree (value);
+		return gdata_parser_error_required_property_missing (root_node, "value", error);
+	}
+
+	rel = xmlGetProp (root_node, (xmlChar*) "rel");
+	label = xmlGetProp (root_node, (xmlChar*) "label");
+	if ((rel == NULL || *rel == '\0') && (label == NULL || *label == '\0')) {
+		xmlFree (value);
+		xmlFree (rel);
+		xmlFree (label);
+		return gdata_parser_error_required_property_missing (root_node, "rel", error);
+	} else if (rel != NULL && label != NULL) {
+		/* Can't have both set at once */
+		xmlFree (value);
+		xmlFree (rel);
+		xmlFree (label);
+		return gdata_parser_error_mutexed_properties (root_node, "rel", "label", error);
+	}
+
+	priv->value = (gchar*) value;
+	priv->relation_type = (gchar*) rel;
+	priv->label = (gchar*) label;
+
+	return TRUE;
+}
+
+static void
+pre_get_xml (GDataParsable *parsable, GString *xml_string)
+{
+	GDataGContactExternalIDPrivate *priv = GDATA_GCONTACT_EXTERNAL_ID (parsable)->priv;
+
+	gdata_parser_string_append_escaped (xml_string, " value='", priv->value, "'");
+
+	if (priv->relation_type != NULL)
+		g_string_append_printf (xml_string, " rel='%s'", priv->relation_type);
+	else if (priv->label != NULL)
+		gdata_parser_string_append_escaped (xml_string, " label='", priv->label, "'");
+	else
+		g_assert_not_reached ();
+}
+
+static void
+get_namespaces (GDataParsable *parsable, GHashTable *namespaces)
+{
+	g_hash_table_insert (namespaces, (gchar*) "gContact", (gchar*) "http://schemas.google.com/contact/2008";);
+}
+
+/**
+ * gdata_gcontact_external_id_new:
+ * @value: the value of the external ID
+ * @relation_type: the type of external ID, or %NULL
+ * @label: a free-form label for the external ID, or %NULL
+ *
+ * Creates a new #GDataGContactExternalID. More information is available in the <ulink type="http"
+ * url="http://code.google.com/apis/contacts/docs/3.0/reference.html#gcExternalId";>gContact specification</ulink>.
+ *
+ * Exactly one of @relation_type and @label should be provided; the other must be %NULL.
+ *
+ * Return value: a new #GDataGContactExternalID; unref with g_object_unref()
+ *
+ * Since: 0.7.0
+ **/
+GDataGContactExternalID *
+gdata_gcontact_external_id_new (const gchar *value, const gchar *relation_type, const gchar *label)
+{
+	g_return_val_if_fail (value != NULL, NULL);
+	g_return_val_if_fail ((relation_type != NULL && *relation_type != '\0' && label == NULL) ||
+	                      (relation_type == NULL && label != NULL && *label != '\0'), NULL);
+
+	return g_object_new (GDATA_TYPE_GCONTACT_EXTERNAL_ID, "value", value, "relation-type", relation_type, "label", label, NULL);
+}
+
+/**
+ * gdata_gcontact_external_id_compare:
+ * @a: a #GDataGContactExternalID, or %NULL
+ * @b: another #GDataGContactExternalID, or %NULL
+ *
+ * Compares the two external IDs in a strcmp() fashion. %NULL values are handled gracefully, with
+ * <code class="literal">0</code> returned if both @a and @b are %NULL, <code class="literal">-1</code> if @a is %NULL
+ * and <code class="literal">1</code> if @b is %NULL.
+ *
+ * The comparison of non-%NULL values is done on the basis of the @value, @relation_type and @label properties of the #GDataGContactExternalID<!-- -->s.
+ *
+ * Return value: <code class="literal">0</code> if @a equals @b, <code class="literal">-1</code> or <code class="literal">1</code> as
+ * appropriate otherwise
+ *
+ * Since: 0.7.0
+ **/
+gint
+gdata_gcontact_external_id_compare (const GDataGContactExternalID *a, const GDataGContactExternalID *b)
+{
+	if (a == NULL && b != NULL)
+		return -1;
+	else if (a != NULL && b == NULL)
+		return 1;
+
+	if (a == b)
+		return 0;
+
+	if (g_strcmp0 (a->priv->value, b->priv->value) == 0 &&
+	    g_strcmp0 (a->priv->relation_type, b->priv->relation_type) == 0 &&
+	    g_strcmp0 (a->priv->label, b->priv->label) == 0)
+		return 0;
+	return 1;
+}
+
+/**
+ * gdata_gcontact_external_id_get_value:
+ * @self: a #GDataGContactExternalID
+ *
+ * Gets the #GDataGContactExternalID:value property.
+ *
+ * Return value: the external ID's value
+ *
+ * Since: 0.7.0
+ **/
+const gchar *
+gdata_gcontact_external_id_get_value (GDataGContactExternalID *self)
+{
+	g_return_val_if_fail (GDATA_IS_GCONTACT_EXTERNAL_ID (self), NULL);
+	return self->priv->value;
+}
+
+/**
+ * gdata_gcontact_external_id_set_value:
+ * @self: a #GDataGContactExternalID
+ * @value: the new value for the external ID
+ *
+ * Sets the #GDataGContactExternalID:value property to @value.
+ *
+ * Since: 0.7.0
+ **/
+void
+gdata_gcontact_external_id_set_value (GDataGContactExternalID *self, const gchar *value)
+{
+	g_return_if_fail (GDATA_IS_GCONTACT_EXTERNAL_ID (self));
+	g_return_if_fail (value != NULL);
+
+	g_free (self->priv->value);
+	self->priv->value = g_strdup (value);
+	g_object_notify (G_OBJECT (self), "value");
+}
+
+/**
+ * gdata_gcontact_external_id_get_relation_type:
+ * @self: a #GDataGContactExternalID
+ *
+ * Gets the #GDataGContactExternalID:relation-type property.
+ *
+ * Return value: the type of the relation, or %NULL
+ *
+ * Since: 0.7.0
+ **/
+const gchar *
+gdata_gcontact_external_id_get_relation_type (GDataGContactExternalID *self)
+{
+	g_return_val_if_fail (GDATA_IS_GCONTACT_EXTERNAL_ID (self), NULL);
+	return self->priv->relation_type;
+}
+
+/**
+ * gdata_gcontact_external_id_set_relation_type:
+ * @self: a #GDataGContactExternalID
+ * @relation_type: the new type for the external ID, or %NULL
+ *
+ * Sets the #GDataGContactExternalID:relation-type property to @relation_type,
+ * such as %GDATA_GCONTACT_EXTERNAL_ID_HOME or %GDATA_GCONTACT_EXTERNAL_ID_FREE_BUSY.
+ *
+ * If @relation_type is %NULL, the relation type will be unset. When the #GDataGContactExternalID is used in a query, however,
+ * exactly one of #GDataGContactExternalID:relation-type and #GDataGContactExternalID:label must be %NULL.
+ *
+ * Since: 0.7.0
+ **/
+void
+gdata_gcontact_external_id_set_relation_type (GDataGContactExternalID *self, const gchar *relation_type)
+{
+	g_return_if_fail (GDATA_IS_GCONTACT_EXTERNAL_ID (self));
+	g_return_if_fail (relation_type == NULL || *relation_type != '\0');
+
+	g_free (self->priv->relation_type);
+	self->priv->relation_type = g_strdup (relation_type);
+	g_object_notify (G_OBJECT (self), "relation-type");
+}
+
+/**
+ * gdata_gcontact_external_id_get_label:
+ * @self: a #GDataGContactExternalID
+ *
+ * Gets the #GDataGContactExternalID:label property.
+ *
+ * Return value: a free-form label for the external ID, or %NULL
+ *
+ * Since: 0.7.0
+ **/
+const gchar *
+gdata_gcontact_external_id_get_label (GDataGContactExternalID *self)
+{
+	g_return_val_if_fail (GDATA_IS_GCONTACT_EXTERNAL_ID (self), NULL);
+	return self->priv->label;
+}
+
+/**
+ * gdata_gcontact_external_id_set_label:
+ * @self: a #GDataGContactExternalID
+ * @label: the new free-form label for the external ID, or %NULL
+ *
+ * Sets the #GDataGContactExternalID:label property to @label.
+ *
+ * If @label is %NULL, the label will be unset. When the #GDataGContactExternalID is used in a query, however,
+ * exactly one of #GDataGContactExternalID:relation-type and #GDataGContactExternalID:label must be %NULL.
+ *
+ * Since: 0.7.0
+ **/
+void
+gdata_gcontact_external_id_set_label (GDataGContactExternalID *self, const gchar *label)
+{
+	g_return_if_fail (GDATA_IS_GCONTACT_EXTERNAL_ID (self));
+	g_return_if_fail (label == NULL || *label != '\0');
+
+	g_free (self->priv->label);
+	self->priv->label = g_strdup (label);
+	g_object_notify (G_OBJECT (self), "label");
+}
diff --git a/gdata/gcontact/gdata-gcontact-external-id.h b/gdata/gcontact/gdata-gcontact-external-id.h
new file mode 100644
index 0000000..2da8bfc
--- /dev/null
+++ b/gdata/gcontact/gdata-gcontact-external-id.h
@@ -0,0 +1,128 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/*
+ * GData Client
+ * Copyright (C) Philip Withnall 2010 <philip tecnocode co uk>
+ *
+ * GData Client is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * GData Client is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GData Client.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GDATA_GCONTACT_EXTERNAL_ID_H
+#define GDATA_GCONTACT_EXTERNAL_ID_H
+
+#include <glib.h>
+#include <glib-object.h>
+
+#include <gdata/gdata-parsable.h>
+
+G_BEGIN_DECLS
+
+/**
+ * GDATA_GCONTACT_EXTERNAL_ID_ACCOUNT:
+ *
+ * The relation type URI for an account number identifier.
+ *
+ * For more information, see the <ulink type="http" url="http://code.google.com/apis/contacts/docs/3.0/reference.html#gcExternalId";>
+ * gContact specification</ulink>.
+ *
+ * Since: 0.7.0
+ **/
+#define GDATA_GCONTACT_EXTERNAL_ID_ACCOUNT "account"
+
+/**
+ * GDATA_GCONTACT_EXTERNAL_ID_CUSTOMER:
+ *
+ * The relation type URI for a customer identifier.
+ *
+ * For more information, see the <ulink type="http" url="http://code.google.com/apis/contacts/docs/3.0/reference.html#gcExternalId";>
+ * gContact specification</ulink>.
+ *
+ * Since: 0.7.0
+ **/
+#define GDATA_GCONTACT_EXTERNAL_ID_CUSTOMER "customer"
+
+/**
+ * GDATA_GCONTACT_EXTERNAL_ID_NETWORK:
+ *
+ * The relation type URI for a network identifier.
+ *
+ * For more information, see the <ulink type="http" url="http://code.google.com/apis/contacts/docs/3.0/reference.html#gcExternalId";>
+ * gContact specification</ulink>.
+ *
+ * Since: 0.7.0
+ **/
+#define GDATA_GCONTACT_EXTERNAL_ID_NETWORK "network"
+
+/**
+ * GDATA_GCONTACT_EXTERNAL_ID_ORGANIZATION:
+ *
+ * The relation type URI for an identifier related to an organization the contact is associated with.
+ *
+ * For more information, see the <ulink type="http" url="http://code.google.com/apis/contacts/docs/3.0/reference.html#gcExternalId";>
+ * gContact specification</ulink>.
+ *
+ * Since: 0.7.0
+ **/
+#define GDATA_GCONTACT_EXTERNAL_ID_ORGANIZATION "organization"
+
+#define GDATA_TYPE_GCONTACT_EXTERNAL_ID		(gdata_gcontact_external_id_get_type ())
+#define GDATA_GCONTACT_EXTERNAL_ID(o)		(G_TYPE_CHECK_INSTANCE_CAST ((o), GDATA_TYPE_GCONTACT_EXTERNAL_ID, GDataGContactExternalID))
+#define GDATA_GCONTACT_EXTERNAL_ID_CLASS(k)	(G_TYPE_CHECK_CLASS_CAST((k), GDATA_TYPE_GCONTACT_EXTERNAL_ID, GDataGContactExternalIDClass))
+#define GDATA_IS_GCONTACT_EXTERNAL_ID(o)	(G_TYPE_CHECK_INSTANCE_TYPE ((o), GDATA_TYPE_GCONTACT_EXTERNAL_ID))
+#define GDATA_IS_GCONTACT_EXTERNAL_ID_CLASS(k)	(G_TYPE_CHECK_CLASS_TYPE ((k), GDATA_TYPE_GCONTACT_EXTERNAL_ID))
+#define GDATA_GCONTACT_EXTERNAL_ID_GET_CLASS(o)	(G_TYPE_INSTANCE_GET_CLASS ((o), GDATA_TYPE_GCONTACT_EXTERNAL_ID, GDataGContactExternalIDClass))
+
+typedef struct _GDataGContactExternalIDPrivate	GDataGContactExternalIDPrivate;
+
+/**
+ * GDataGContactExternalID:
+ *
+ * All the fields in the #GDataGContactExternalID structure are private and should never be accessed directly.
+ *
+ * Since: 0.7.0
+ **/
+typedef struct {
+	GDataParsable parent;
+	GDataGContactExternalIDPrivate *priv;
+} GDataGContactExternalID;
+
+/**
+ * GDataGContactExternalIDClass:
+ *
+ * All the fields in the #GDataGContactExternalIDClass structure are private and should never be accessed directly.
+ *
+ * Since: 0.7.0
+ **/
+typedef struct {
+	/*< private >*/
+	GDataParsableClass parent;
+} GDataGContactExternalIDClass;
+
+GType gdata_gcontact_external_id_get_type (void) G_GNUC_CONST;
+
+GDataGContactExternalID *gdata_gcontact_external_id_new (const gchar *value, const gchar *relation_type,
+                                                         const gchar *label) G_GNUC_WARN_UNUSED_RESULT G_GNUC_MALLOC;
+gint gdata_gcontact_external_id_compare (const GDataGContactExternalID *a, const GDataGContactExternalID *b);
+
+const gchar *gdata_gcontact_external_id_get_value (GDataGContactExternalID *self);
+void gdata_gcontact_external_id_set_value (GDataGContactExternalID *self, const gchar *value);
+
+const gchar *gdata_gcontact_external_id_get_relation_type (GDataGContactExternalID *self);
+void gdata_gcontact_external_id_set_relation_type (GDataGContactExternalID *self, const gchar *relation_type);
+
+const gchar *gdata_gcontact_external_id_get_label (GDataGContactExternalID *self);
+void gdata_gcontact_external_id_set_label (GDataGContactExternalID *self, const gchar *label);
+
+G_END_DECLS
+
+#endif /* !GDATA_GCONTACT_EXTERNAL_ID_H */
diff --git a/gdata/gdata.h b/gdata/gdata.h
index 1351d3c..825948c 100644
--- a/gdata/gdata.h
+++ b/gdata/gdata.h
@@ -56,6 +56,7 @@
 /* GContact */
 #include <gdata/gcontact/gdata-gcontact-calendar.h>
 #include <gdata/gcontact/gdata-gcontact-event.h>
+#include <gdata/gcontact/gdata-gcontact-external-id.h>
 #include <gdata/gcontact/gdata-gcontact-jot.h>
 #include <gdata/gcontact/gdata-gcontact-relation.h>
 #include <gdata/gcontact/gdata-gcontact-website.h>
diff --git a/gdata/gdata.symbols b/gdata/gdata.symbols
index b086a72..5716d03 100644
--- a/gdata/gdata.symbols
+++ b/gdata/gdata.symbols
@@ -805,3 +805,15 @@ gdata_contacts_contact_set_billing_information
 gdata_contacts_contact_get_user_defined_field
 gdata_contacts_contact_get_user_defined_fields
 gdata_contacts_contact_set_user_defined_field
+gdata_gcontact_external_id_get_type
+gdata_gcontact_external_id_new
+gdata_gcontact_external_id_compare
+gdata_gcontact_external_id_get_value
+gdata_gcontact_external_id_set_value
+gdata_gcontact_external_id_get_relation_type
+gdata_gcontact_external_id_set_relation_type
+gdata_gcontact_external_id_get_label
+gdata_gcontact_external_id_set_label
+gdata_contacts_contact_add_external_id
+gdata_contacts_contact_get_external_ids
+gdata_contacts_contact_remove_all_external_ids
diff --git a/gdata/services/contacts/gdata-contacts-contact.c b/gdata/services/contacts/gdata-contacts-contact.c
index 2a0eacd..8aeeeda 100644
--- a/gdata/services/contacts/gdata-contacts-contact.c
+++ b/gdata/services/contacts/gdata-contacts-contact.c
@@ -85,6 +85,7 @@ struct _GDataContactsContactPrivate {
 	GList *websites; /* GDataGContactWebsite */
 	GList *events; /* GDataGContactEvent */
 	GList *calendars; /* GDataGContactCalendar */
+	GList *external_ids; /* GDataGContactExternalID */
 	gchar *billing_information;
 	gchar *directory_server;
 	gchar *gender;
@@ -445,6 +446,7 @@ gdata_contacts_contact_dispose (GObject *object)
 	gdata_contacts_contact_remove_all_websites (self);
 	gdata_contacts_contact_remove_all_events (self);
 	gdata_contacts_contact_remove_all_calendars (self);
+	gdata_contacts_contact_remove_all_external_ids (self);
 
 	/* Chain up to the parent class */
 	G_OBJECT_CLASS (gdata_contacts_contact_parent_class)->dispose (object);
@@ -668,6 +670,8 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 		                                             gdata_contacts_contact_add_website, self, &success, error) == TRUE ||
 		    gdata_parser_object_from_element_setter (node, "calendarLink", P_REQUIRED, GDATA_TYPE_GCONTACT_CALENDAR,
 		                                             gdata_contacts_contact_add_calendar, self, &success, error) == TRUE ||
+		    gdata_parser_object_from_element_setter (node, "externalId", P_REQUIRED, GDATA_TYPE_GCONTACT_EXTERNAL_ID,
+		                                             gdata_contacts_contact_add_external_id, self, &success, error) == TRUE ||
 		    gdata_parser_string_from_element (node, "nickname", P_REQUIRED | P_NO_DUPES, &(self->priv->nickname), &success, error) == TRUE ||
 		    gdata_parser_string_from_element (node, "billingInformation", P_REQUIRED | P_NO_DUPES | P_NON_EMPTY,
 		                                      &(self->priv->billing_information), &success, error) == TRUE ||
@@ -858,6 +862,7 @@ get_xml (GDataParsable *parsable, GString *xml_string)
 	get_child_xml (priv->websites, xml_string);
 	get_child_xml (priv->events, xml_string);
 	get_child_xml (priv->calendars, xml_string);
+	get_child_xml (priv->external_ids, xml_string);
 
 	/* Extended properties */
 	g_hash_table_foreach (priv->extended_properties, (GHFunc) get_extended_property_xml_cb, xml_string);
@@ -2361,6 +2366,66 @@ gdata_contacts_contact_remove_all_calendars (GDataContactsContact *self)
 }
 
 /**
+ * gdata_contacts_contact_add_external_id:
+ * @self: a #GDataContactsContact
+ * @external_id: a #GDataGContactExternalID to add
+ *
+ * Adds an external ID to the contact's list of external IDs and increments its reference count.
+ *
+ * Duplicate IDs will not be added to the list.
+ *
+ * Since: 0.7.0
+ **/
+void
+gdata_contacts_contact_add_external_id (GDataContactsContact *self, GDataGContactExternalID *external_id)
+{
+	g_return_if_fail (GDATA_IS_CONTACTS_CONTACT (self));
+	g_return_if_fail (GDATA_IS_GCONTACT_EXTERNAL_ID (external_id));
+
+	if (g_list_find_custom (self->priv->external_ids, external_id, (GCompareFunc) gdata_gcontact_external_id_compare) == NULL)
+		self->priv->external_ids = g_list_append (self->priv->external_ids, g_object_ref (external_id));
+}
+
+/**
+ * gdata_contacts_contact_get_external_ids:
+ * @self: a #GDataContactsContact
+ *
+ * Gets a list of the external IDs of the contact.
+ *
+ * Return value: a #GList of #GDataGContactExternalID<!-- -->s, or %NULL
+ *
+ * Since: 0.7.0
+ **/
+GList *
+gdata_contacts_contact_get_external_ids (GDataContactsContact *self)
+{
+	g_return_val_if_fail (GDATA_IS_CONTACTS_CONTACT (self), NULL);
+	return self->priv->external_ids;
+}
+
+/**
+ * gdata_contacts_contact_remove_all_external_ids:
+ * @self: a #GDataContactsContact
+ *
+ * Removes all external IDs from the contact.
+ *
+ * Since: 0.7.0
+ **/
+void
+gdata_contacts_contact_remove_all_external_ids (GDataContactsContact *self)
+{
+	GDataContactsContactPrivate *priv = self->priv;
+
+	g_return_if_fail (GDATA_IS_CONTACTS_CONTACT (self));
+
+	if (priv->external_ids != NULL) {
+		g_list_foreach (priv->external_ids, (GFunc) g_object_unref, NULL);
+		g_list_free (priv->external_ids);
+	}
+	priv->external_ids = NULL;
+}
+
+/**
  * gdata_contacts_contact_get_extended_property:
  * @self: a #GDataContactsContact
  * @name: the property name; an arbitrary, unique string
@@ -2490,8 +2555,6 @@ gdata_contacts_contact_get_user_defined_fields (GDataContactsContact *self)
  *
  * To unset a field, set @value to %NULL.
  *
- * Return value: %TRUE if the field was updated or deleted successfully, %FALSE otherwise
- *
  * Since: 0.7.0
  **/
 void
diff --git a/gdata/services/contacts/gdata-contacts-contact.h b/gdata/services/contacts/gdata-contacts-contact.h
index d52caa6..e44e56f 100644
--- a/gdata/services/contacts/gdata-contacts-contact.h
+++ b/gdata/services/contacts/gdata-contacts-contact.h
@@ -32,6 +32,7 @@
 #include <gdata/gd/gdata-gd-postal-address.h>
 #include <gdata/gcontact/gdata-gcontact-calendar.h>
 #include <gdata/gcontact/gdata-gcontact-event.h>
+#include <gdata/gcontact/gdata-gcontact-external-id.h>
 #include <gdata/gcontact/gdata-gcontact-jot.h>
 #include <gdata/gcontact/gdata-gcontact-relation.h>
 #include <gdata/gcontact/gdata-gcontact-website.h>
@@ -248,6 +249,10 @@ GList *gdata_contacts_contact_get_calendars (GDataContactsContact *self);
 GDataGContactCalendar *gdata_contacts_contact_get_primary_calendar (GDataContactsContact *self);
 void gdata_contacts_contact_remove_all_calendars (GDataContactsContact *self);
 
+void gdata_contacts_contact_add_external_id (GDataContactsContact *self, GDataGContactExternalID *external_id);
+GList *gdata_contacts_contact_get_external_ids (GDataContactsContact *self);
+void gdata_contacts_contact_remove_all_external_ids (GDataContactsContact *self);
+
 const gchar *gdata_contacts_contact_get_extended_property (GDataContactsContact *self, const gchar *name);
 GHashTable *gdata_contacts_contact_get_extended_properties (GDataContactsContact *self);
 gboolean gdata_contacts_contact_set_extended_property (GDataContactsContact *self, const gchar *name, const gchar *value);
diff --git a/gdata/tests/contacts.c b/gdata/tests/contacts.c
index e44b5c3..423655c 100644
--- a/gdata/tests/contacts.c
+++ b/gdata/tests/contacts.c
@@ -160,6 +160,7 @@ test_insert_simple (gconstpointer service)
 	GDataGContactWebsite *website;
 	GDataGContactEvent *event;
 	GDataGContactCalendar *calendar;
+	GDataGContactExternalID *external_id;
 	gchar *xml, *nickname, *billing_information, *directory_server, *gender, *initials, *maiden_name, *mileage, *occupation;
 	gchar *priority, *sensitivity, *short_name, *subject;
 	GList *list;
@@ -254,6 +255,10 @@ test_insert_simple (gconstpointer service)
 	gdata_contacts_contact_add_calendar (contact, calendar);
 	g_object_unref (calendar);
 
+	external_id = gdata_gcontact_external_id_new ("Number Six", GDATA_GCONTACT_EXTERNAL_ID_ORGANIZATION, NULL);
+	gdata_contacts_contact_add_external_id (contact, external_id);
+	g_object_unref (external_id);
+
 	/* Add some extended properties */
 	g_assert (gdata_contacts_contact_set_extended_property (contact, "TITLE", NULL) == TRUE);
 	g_assert (gdata_contacts_contact_set_extended_property (contact, "ROLE", "") == TRUE);
@@ -356,6 +361,7 @@ test_insert_simple (gconstpointer service)
 				"<gContact:website href='http://example.com/' rel='profile' primary='true'/>"
 				"<gContact:event rel='anniversary'><gd:when startTime='1900-01-01'/></gContact:event>"
 				"<gContact:calendarLink href='http://calendar.example.com/' rel='home' primary='true'/>"
+				"<gContact:externalId value='Number Six' rel='organization'/>"
 				"<gd:extendedProperty name='CALURI'>http://example.com/</gd:extendedProperty>"
 				"<gContact:userDefinedField key='Favourite colour' value='Blue'/>"
 				"<gContact:userDefinedField key='Owes me' value='£10'/>"
@@ -469,6 +475,11 @@ test_insert_simple (gconstpointer service)
 
 	g_assert (GDATA_IS_GCONTACT_CALENDAR (gdata_contacts_contact_get_primary_calendar (new_contact)));
 
+	/* External IDs */
+	list = gdata_contacts_contact_get_external_ids (new_contact);
+	g_assert_cmpuint (g_list_length (list), ==, 1);
+	g_assert (GDATA_IS_GCONTACT_EXTERNAL_ID (list->data));
+
 	/* Extended properties */
 	g_assert_cmpstr (gdata_contacts_contact_get_extended_property (new_contact, "CALURI"), ==, "http://example.com/";);
 	g_assert (gdata_contacts_contact_get_extended_property (new_contact, "non-existent") == NULL);
@@ -533,6 +544,9 @@ test_insert_simple (gconstpointer service)
 	g_assert (gdata_contacts_contact_get_calendars (new_contact) == NULL);
 	g_assert (gdata_contacts_contact_get_primary_calendar (new_contact) == NULL);
 
+	gdata_contacts_contact_remove_all_external_ids (new_contact);
+	g_assert (gdata_contacts_contact_get_external_ids (new_contact) == NULL);
+
 	g_free (edited);
 	g_object_unref (contact);
 	g_object_unref (new_contact);
@@ -703,6 +717,7 @@ test_parser_minimal (gconstpointer service)
 	g_assert (gdata_contacts_contact_get_events (contact) == NULL);
 	g_assert (gdata_contacts_contact_get_calendars (contact) == NULL);
 	g_assert (gdata_contacts_contact_get_primary_calendar (contact) == NULL);
+	g_assert (gdata_contacts_contact_get_external_ids (contact) == NULL);
 
 	g_object_unref (contact);
 }
@@ -761,6 +776,8 @@ test_parser_normal (gconstpointer service)
 			"<gContact:calendarLink href='http://example.com/' rel='free-busy' primary='true'/>"
 			"<gContact:calendarLink href='http://example.com/' label='Gig list' primary='false'/>"
 			"<gContact:calendarLink href='http://foo.com/calendar' rel='home'/>"
+			"<gContact:externalId value='Number Six' label='The Prisoner'/>"
+			"<gContact:externalId value='1545' rel='account'/>"
 		"</entry>", -1, &error));
 	g_assert_no_error (error);
 	g_assert (GDATA_IS_CONTACTS_CONTACT (contact));
@@ -897,6 +914,13 @@ test_parser_normal (gconstpointer service)
 	g_assert (gdata_gcontact_calendar_get_label (GDATA_GCONTACT_CALENDAR (list->data)) == NULL);
 	g_assert (gdata_gcontact_calendar_is_primary (GDATA_GCONTACT_CALENDAR (list->data)) == FALSE);
 
+	/* External IDs */
+	list = gdata_contacts_contact_get_external_ids (contact);
+	g_assert_cmpuint (g_list_length (list), ==, 2);
+
+	g_assert (GDATA_IS_GCONTACT_EXTERNAL_ID (list->data));
+	g_assert (GDATA_IS_GCONTACT_EXTERNAL_ID (list->next->data));
+
 	g_object_unref (contact);
 }
 
@@ -1023,6 +1047,9 @@ test_parser_error_handling (gconstpointer service)
 	/* gContact:calendar */
 	TEST_XML_ERROR_HANDLING ("<gContact:calendarLink/>");
 
+	/* gContact:externalId */
+	TEST_XML_ERROR_HANDLING ("<gContact:externalId/>");
+
 #undef TEST_XML_ERROR_HANDLING
 }
 
diff --git a/gdata/tests/general.c b/gdata/tests/general.c
index 6ac91f6..9c5eecc 100644
--- a/gdata/tests/general.c
+++ b/gdata/tests/general.c
@@ -2554,6 +2554,91 @@ test_gcontact_event_error_handling (void)
 }
 
 static void
+test_gcontact_external_id (void)
+{
+	GDataGContactExternalID *id, *id2;
+	gchar *xml;
+	GError *error = NULL;
+
+	id = GDATA_GCONTACT_EXTERNAL_ID (gdata_parsable_new_from_xml (GDATA_TYPE_GCONTACT_EXTERNAL_ID,
+		"<gContact:externalId xmlns:gContact='http://schemas.google.com/contact/2008' rel='account' value='5'/>", -1, &error));
+	g_assert_no_error (error);
+	g_assert (GDATA_IS_GCONTACT_EXTERNAL_ID (id));
+	g_clear_error (&error);
+
+	/* Check the properties */
+	g_assert_cmpstr (gdata_gcontact_external_id_get_value (id), ==, "5");
+	g_assert_cmpstr (gdata_gcontact_external_id_get_relation_type (id), ==, GDATA_GCONTACT_EXTERNAL_ID_ACCOUNT);
+	g_assert (gdata_gcontact_external_id_get_label (id) == NULL);
+
+	/* Compare it against another identical external ID */
+	id2 = gdata_gcontact_external_id_new ("5", GDATA_GCONTACT_EXTERNAL_ID_ACCOUNT, NULL);
+	g_assert_cmpint (gdata_gcontact_external_id_compare (id, id2), ==, 0);
+
+	/* â?¦and a different one */
+	gdata_gcontact_external_id_set_value (id2, "http://identifying.uri";);
+	g_assert_cmpint (gdata_gcontact_external_id_compare (id, id2), !=, 0);
+	g_object_unref (id2);
+
+	/* More comparisons */
+	g_assert_cmpint (gdata_gcontact_external_id_compare (id, NULL), ==, 1);
+	g_assert_cmpint (gdata_gcontact_external_id_compare (NULL, id), ==, -1);
+	g_assert_cmpint (gdata_gcontact_external_id_compare (NULL, NULL), ==, 0);
+	g_assert_cmpint (gdata_gcontact_external_id_compare (id, id), ==, 0);
+
+	/* Check the outputted XML is the same */
+	xml = gdata_parsable_get_xml (GDATA_PARSABLE (id));
+	g_assert_cmpstr (xml, ==,
+			 "<gContact:externalId xmlns='http://www.w3.org/2005/Atom' xmlns:gContact='http://schemas.google.com/contact/2008' "
+				"value='5' rel='account'/>");
+	g_free (xml);
+	g_object_unref (id);
+
+	/* Now parse an ID with less information available */
+	id = GDATA_GCONTACT_EXTERNAL_ID (gdata_parsable_new_from_xml (GDATA_TYPE_GCONTACT_EXTERNAL_ID,
+		"<gContact:externalId xmlns:gContact='http://schemas.google.com/contact/2008' value='' label='&lt;a&gt;'/>", -1, &error));
+	g_assert_no_error (error);
+	g_assert (GDATA_IS_GCONTACT_EXTERNAL_ID (id));
+	g_clear_error (&error);
+
+	/* Check the properties */
+	g_assert_cmpstr (gdata_gcontact_external_id_get_value (id), ==, "");
+	g_assert (gdata_gcontact_external_id_get_relation_type (id) == NULL);
+	g_assert_cmpstr (gdata_gcontact_external_id_get_label (id), ==, "<a>");
+
+	/* Check the outputted XML is still OK */
+	xml = gdata_parsable_get_xml (GDATA_PARSABLE (id));
+	g_assert_cmpstr (xml, ==,
+			 "<gContact:externalId xmlns='http://www.w3.org/2005/Atom' xmlns:gContact='http://schemas.google.com/contact/2008' "
+				"value='' label='&lt;a&gt;'/>");
+	g_free (xml);
+	g_object_unref (id);
+}
+
+static void
+test_gcontact_external_id_error_handling (void)
+{
+	GDataGContactExternalID *id;
+	GError *error = NULL;
+
+#define TEST_XML_ERROR_HANDLING(x) id = GDATA_GCONTACT_EXTERNAL_ID (gdata_parsable_new_from_xml (GDATA_TYPE_GCONTACT_EXTERNAL_ID,\
+		"<gContact:externalId xmlns:gContact='http://schemas.google.com/contact/2008' "\
+			x\
+		"/>", -1, &error));\
+	g_assert_error (error, GDATA_SERVICE_ERROR, GDATA_SERVICE_ERROR_PROTOCOL_ERROR);\
+	g_assert (id == NULL);\
+	g_clear_error (&error)
+
+	TEST_XML_ERROR_HANDLING ("rel='account'"); /* no value */
+	TEST_XML_ERROR_HANDLING ("value='foo'"); /* no rel or label */
+	TEST_XML_ERROR_HANDLING ("value='foo' rel=''"); /* empty rel */
+	TEST_XML_ERROR_HANDLING ("value='foo' label=''"); /* empty label */
+	TEST_XML_ERROR_HANDLING ("value='foo' rel='organization' label='Other'"); /* rel and label */
+
+#undef TEST_XML_ERROR_HANDLING
+}
+
+static void
 test_gcontact_jot (void)
 {
 	GDataGContactJot *jot, *jot2;
@@ -2842,6 +2927,8 @@ main (int argc, char *argv[])
 	g_test_add_func ("/gcontact/calendar/error_handling", test_gcontact_calendar_error_handling);
 	g_test_add_func ("/gcontact/event", test_gcontact_event);
 	g_test_add_func ("/gcontact/event/error_handling", test_gcontact_event_error_handling);
+	g_test_add_func ("/gcontact/external_id", test_gcontact_external_id);
+	g_test_add_func ("/gcontact/external_id/error_handling", test_gcontact_external_id_error_handling);
 	g_test_add_func ("/gcontact/jot", test_gcontact_jot);
 	g_test_add_func ("/gcontact/jot/error_handling", test_gcontact_jot_error_handling);
 	g_test_add_func ("/gcontact/relation", test_gcontact_relation);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]