Index: libgossip/gossip-contact.h
===================================================================
--- libgossip/gossip-contact.h	(revision 2242)
+++ libgossip/gossip-contact.h	(working copy)
@@ -61,6 +61,11 @@
 	GOSSIP_SUBSCRIPTION_BOTH
 } GossipSubscription;
 
+typedef enum {
+	GOSSIP_CONTACT_CAPABILITY_AUDIO = 1 << 0,
+	GOSSIP_CONTACT_CAPABILITY_VIDEO = 1 << 1,
+} GossipContactCapabilities;
+
 GType              gossip_contact_get_gtype                 (void) G_GNUC_CONST;
 
 GossipContact *    gossip_contact_new                       (GossipContactType   type,
@@ -87,6 +92,8 @@
 GList *            gossip_contact_get_presence_list         (GossipContact      *contact);
 GList *            gossip_contact_get_groups                (GossipContact      *contact);
 GossipSubscription gossip_contact_get_subscription          (GossipContact      *contact);
+GossipContactCapabilities gossip_contact_get_capabilities   (GossipContact      *contact);
+gboolean           gossip_contact_can_voip                  (GossipContact      *contact);
 void               gossip_contact_set_id                    (GossipContact      *contact,
 							     const gchar        *id);
 void               gossip_contact_set_name                  (GossipContact      *contact,
@@ -99,6 +106,8 @@
 							     GList              *categories);
 void               gossip_contact_set_subscription          (GossipContact      *contact,
 							     GossipSubscription  subscription);
+void               gossip_contact_set_capabilities          (GossipContact      *contact,
+							     GossipContactCapabilities capabilities);
 gint               gossip_contact_name_compare              (gconstpointer       a,
 							     gconstpointer       b);
 gint               gossip_contact_name_case_compare         (gconstpointer       a,
Index: libgossip/gossip-utils.c
===================================================================
--- libgossip/gossip-utils.c	(revision 2242)
+++ libgossip/gossip-utils.c	(working copy)
@@ -304,6 +304,9 @@
 	else if (dbus_type_string[0] == 'n') {
 		return G_TYPE_INT;
 	}
+	else if (dbus_type_string[0] == 'i') {
+		return G_TYPE_INT;
+	}
 
 	g_assert_not_reached ();
 	return G_TYPE_NONE;
Index: libgossip/libgossip-marshal.list
===================================================================
--- libgossip/libgossip-marshal.list	(revision 2242)
+++ libgossip/libgossip-marshal.list	(working copy)
@@ -10,4 +10,6 @@
 VOID:OBJECT,POINTER
 VOID:OBJECT,INT
 VOID:OBJECT,OBJECT,INT
+VOID:OBJECT,UINT
+VOID:OBJECT,UINT,UINT
 STRING:OBJECT
Index: libgossip/gossip-session.c
===================================================================
--- libgossip/gossip-session.c	(revision 2242)
+++ libgossip/gossip-session.c	(working copy)
@@ -106,6 +106,9 @@
 static void            session_protocol_new_message              (GossipProtocol       *protocol,
 								  GossipMessage        *message,
 								  GossipSession        *session);
+static void            session_protocol_voip_incoming            (GossipProtocol       *protocol,
+								  GossipContact        *contact,
+								  GossipSession        *session);
 static void            session_protocol_contact_added            (GossipProtocol       *protocol,
 								  GossipContact        *contact,
 								  GossipSession        *session);
@@ -147,6 +150,7 @@
 	PROTOCOL_DISCONNECTING,
 	PROTOCOL_ERROR,
 	NEW_MESSAGE,
+	VOIP_INCOMING,
 	CONTACT_ADDED,
 	CONTACT_REMOVED,
 	COMPOSING,
@@ -266,6 +270,16 @@
 			      G_TYPE_NONE,
 			      1, GOSSIP_TYPE_MESSAGE);
 
+	signals[VOIP_INCOMING] =
+		g_signal_new ("voip-incoming",
+			      G_TYPE_FROM_CLASS (klass),
+			      G_SIGNAL_RUN_LAST,
+			      0,
+			      NULL, NULL,
+			      libgossip_marshal_VOID__OBJECT,
+			      G_TYPE_NONE,
+			      1, GOSSIP_TYPE_CONTACT);
+
 	signals[CONTACT_ADDED] =
 		g_signal_new ("contact-added",
 			      G_TYPE_FROM_CLASS (klass),
@@ -400,6 +414,9 @@
 	g_signal_connect (protocol, "new_message",
 			  G_CALLBACK (session_protocol_new_message),
 			  session);
+	g_signal_connect (protocol, "voip-incoming",
+			  G_CALLBACK (session_protocol_voip_incoming),
+			  session);
 	g_signal_connect (protocol, "contact-added",
 			  G_CALLBACK (session_protocol_contact_added),
 			  session);
@@ -555,6 +572,15 @@
 }
 
 static void
+session_protocol_voip_incoming (GossipProtocol *protocol,
+			      GossipContact  *contact,
+			      GossipSession  *session)
+{
+	/* Just relay the signal */
+	g_signal_emit (session, signals[VOIP_INCOMING], 0, contact);
+}
+
+static void
 session_protocol_contact_added (GossipProtocol *protocol,
 				GossipContact  *contact,
 				GossipSession  *session)
@@ -1474,6 +1500,25 @@
 	return GOSSIP_FT_PROVIDER (protocol);
 }
 
+GossipVoipProvider *
+gossip_session_get_voip_provider (GossipSession *session,
+				GossipAccount *account)
+{
+	GossipSessionPriv *priv;
+	GossipProtocol    *protocol;
+
+	g_return_val_if_fail (GOSSIP_IS_SESSION (session), NULL);
+	g_return_val_if_fail (GOSSIP_IS_ACCOUNT (account), NULL);
+
+	priv = GET_PRIV (session);
+
+	protocol = g_hash_table_lookup (priv->accounts, account);
+
+	g_return_val_if_fail (GOSSIP_IS_PROTOCOL (protocol), NULL);
+
+	return GOSSIP_VOIP_PROVIDER (protocol);
+}
+
 GossipContact *
 gossip_session_find_contact (GossipSession *session,
 			     const gchar   *id)
Index: libgossip/Makefile.am
===================================================================
--- libgossip/Makefile.am	(revision 2242)
+++ libgossip/Makefile.am	(working copy)
@@ -59,6 +59,8 @@
 	gossip-ft-provider.h 				\
 	gossip-log.c					\
 	gossip-log.h					\
+	gossip-voip-provider.c	 			\
+	gossip-voip-provider.h 				\
 	gossip-message.c           			\
 	gossip-message.h           			\
 	gossip-conf.h          				\
Index: libgossip/gossip-session.h
===================================================================
--- libgossip/gossip-session.h	(revision 2242)
+++ libgossip/gossip-session.h	(working copy)
@@ -36,6 +36,7 @@
 #include "gossip-contact-manager.h"
 #include "gossip-chatroom-manager.h"
 #include "gossip-ft-provider.h"
+#include "gossip-voip-provider.h"
 
 G_BEGIN_DECLS
 
@@ -72,8 +73,11 @@
 		gossip_session_get_chatroom_provider   (GossipSession          *session,
 							GossipAccount          *account);
 GossipFTProvider *
-		gossip_session_get_ft_provider         (GossipSession          *session,
-							GossipAccount          *account);
+		gossip_session_get_ft_provider         (GossipSession              *session,
+							GossipAccount              *account);
+GossipVoipProvider *
+		gossip_session_get_voip_provider       (GossipSession           *session,
+							GossipAccount           *account);
 
 /* Accounts */
 GossipAccountManager *
Index: libgossip/gossip-contact.c
===================================================================
--- libgossip/gossip-contact.c	(revision 2242)
+++ libgossip/gossip-contact.c	(working copy)
@@ -29,6 +29,7 @@
 
 #include "gossip-contact.h"
 #include "gossip-utils.h"
+#include "libgossip-marshal.h"
 
 #define GET_PRIV(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GOSSIP_TYPE_CONTACT, GossipContactPriv))
 
@@ -49,6 +50,7 @@
 	GossipSubscription  subscription;
 	GossipAvatar       *avatar;
 	GossipAccount      *account;
+	GossipContactCapabilities  capabilities;
 };
 
 static void contact_class_init    (GossipContactClass *class);
@@ -76,7 +78,8 @@
 	PROP_GROUPS,
 	PROP_SUBSCRIPTION,
 	PROP_AVATAR,
-	PROP_ACCOUNT
+	PROP_ACCOUNT,
+	PROP_CAPABILITIES,
 };
 
 static gpointer parent_class = NULL;
@@ -110,7 +113,13 @@
 static void
 contact_class_init (GossipContactClass *class)
 {
-	GObjectClass *object_class;
+	GObjectClass      *object_class;
+	GType              capabilities_type;
+	static GFlagsValue capabilities_flags[] = {
+		{GOSSIP_CONTACT_CAPABILITY_AUDIO, "GOSSIP_CONTACT_CAPABILITY_AUDIO", NULL},
+		{GOSSIP_CONTACT_CAPABILITY_VIDEO, "GOSSIP_CONTACT_CAPABILITY_VIDEO", NULL},
+		{0, NULL, NULL}
+	};
 
 	object_class = G_OBJECT_CLASS (class);
 	parent_class = g_type_class_peek_parent (class);
@@ -184,6 +193,18 @@
 							      GOSSIP_TYPE_ACCOUNT,
 							      G_PARAM_READWRITE));
 
+	capabilities_type = g_flags_register_static("XklEngineFeatures",
+						capabilities_flags);
+
+	g_object_class_install_property (object_class,
+					PROP_CAPABILITIES,
+					g_param_spec_flags ("capabilities",
+							      "Contact Capabilities",
+							      "The capabilities (audio/video/...) of the contact",
+							      capabilities_type,
+							      0,
+							      G_PARAM_READWRITE));
+
 	g_type_class_add_private (object_class, sizeof (GossipContactPriv));
 }
 
@@ -201,6 +222,7 @@
 	priv->account     = NULL;
 	priv->groups      = NULL;
 	priv->avatar      = NULL;
+	priv->capabilities= 0;
 }
 
 static void
@@ -275,6 +297,9 @@
 			g_value_set_object (value, NULL);
 		}
 		break;
+	case PROP_CAPABILITIES:
+		g_value_set_flags (value, priv->capabilities);
+		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
 		break;
@@ -324,6 +349,10 @@
 		gossip_contact_set_account (GOSSIP_CONTACT (object),
 					    GOSSIP_ACCOUNT (g_value_get_object (value)));
 		break;
+	case PROP_CAPABILITIES:
+		gossip_contact_set_capabilities (GOSSIP_CONTACT (object),
+					   g_value_get_flags (value));
+		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
 		break;
@@ -870,3 +899,40 @@
 	}
 }
 
+GossipContactCapabilities
+gossip_contact_get_capabilities (GossipContact *contact)
+{
+	GossipContactPriv *priv;
+
+	g_return_val_if_fail (GOSSIP_IS_CONTACT (contact), 0);
+
+	priv = GET_PRIV (contact);
+	return priv->capabilities;
+}
+
+gboolean
+gossip_contact_can_voip         (GossipContact *contact)
+{
+	GossipContactPriv *priv;
+	gboolean           can_voip;
+
+	g_return_val_if_fail (GOSSIP_IS_CONTACT (contact), 0);
+
+	priv = GET_PRIV (contact);
+	can_voip = priv->capabilities & GOSSIP_CONTACT_CAPABILITY_AUDIO;
+	can_voip = can_voip || (priv->capabilities & GOSSIP_CONTACT_CAPABILITY_VIDEO);
+	return can_voip;
+}
+
+void
+gossip_contact_set_capabilities (GossipContact *contact, GossipContactCapabilities capabilities)
+{
+	GossipContactPriv *priv;
+
+	g_return_if_fail (GOSSIP_IS_CONTACT (contact));
+
+	priv = GET_PRIV (contact);
+	priv->capabilities = capabilities;
+
+	g_object_notify (G_OBJECT (contact), "capabilities");
+}
