diff --git a/configure.ac b/configure.ac
index 6085e9b..363e70f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -32,7 +32,7 @@ AC_COPYRIGHT([
 GLIB_REQUIRED=2.22.0
 GTK_REQUIRED=2.18.0
 GCONF_REQUIRED=1.2.0
-TELEPATHY_GLIB_REQUIRED=0.9.0
+TELEPATHY_GLIB_REQUIRED=0.9.2
 ENCHANT_REQUIRED=1.2.0
 ISO_CODES_REQUIRED=0.35
 LIBNOTIFY_REQUIRED=0.4.4
diff --git a/extensions/Channel_Interface_Conference.xml b/extensions/Channel_Interface_Conference.xml
new file mode 100644
index 0000000..af3e627
--- /dev/null
+++ b/extensions/Channel_Interface_Conference.xml
@@ -0,0 +1,400 @@
+<?xml version="1.0" ?>
+<node name="/Channel_Interface_Conference"
+  xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+  <tp:copyright>Copyright © 2009 Collabora Limited</tp:copyright>
+  <tp:copyright>Copyright © 2009 Nokia Corporation</tp:copyright>
+  <tp:license xmlns="http://www.w3.org/1999/xhtml">
+    <p>This library 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.</p>
+
+    <p>This library 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.</p>
+
+    <p>You should have received a copy of the GNU Lesser General Public
+      License along with this library; if not, write to the Free Software
+      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+      02110-1301, USA.</p>
+  </tp:license>
+  <interface
+    name="org.freedesktop.Telepathy.Channel.Interface.Conference.DRAFT"
+    tp:causes-havoc="experimental">
+    <tp:added version="0.19.0">(draft 1)</tp:added>
+    <tp:requires interface="org.freedesktop.Telepathy.Channel"/>
+    <tp:requires
+      interface="org.freedesktop.Telepathy.Channel.Interface.Group"/>
+
+    <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+      <p>An interface for multi-user conference channels that can "continue
+        from" one or more individual channels.</p>
+
+      <tp:rationale>
+        <p>This interface addresses freedesktop.org <a
+            href="http://bugs.freedesktop.org/show_bug.cgi?id=24906">bug
+            #24906</a> (GSM-compatible conference calls) and <a
+            href="http://bugs.freedesktop.org/show_bug.cgi?id=24939">bug
+            #24939</a> (upgrading calls and chats to multi-user).
+          See those bugs for rationale and use cases.</p>
+
+        <p>Examples of usage:</p>
+
+        <p>Active and held GSM calls C1, C2 can be merged into a single
+          channel Cn with the Conference interface, by calling
+          <code>CreateChannel({...ChannelType: ...Call,
+            ...<tp:member-ref>InitialChannels</tp:member-ref>: [C1, C2]})</code>
+          which returns Cn.</p>
+
+        <p>An XMPP 1-1 conversation C1 can be continued in a newly created
+          multi-user chatroom Cn by calling
+          <code>CreateChannel({...ChannelType: ...Text,
+            ...<tp:member-ref>InitialChannels</tp:member-ref>: [C1]})</code>
+          which returns Cn.</p>
+
+        <p>An XMPP 1-1 conversation C1 can be continued in a specified
+          multi-user chatroom by calling
+          <code>CreateChannel({...ChannelType: ...Text, ...HandleType: ROOM,
+            ...TargetID: 'telepathy@conf.example.com',
+            ...<tp:member-ref>InitialChannels</tp:member-ref>: [C1]})</code>
+          which returns a Conference channel.</p>
+
+        <p>Either of the XMPP cases could work for Call channels, to
+          upgrade from 1-1 Jingle to multi-user Muji. Any of the XMPP cases
+          could in principle work for link-local XMPP (XEP-0174).</p>
+
+        <p>The underlying switchboard representing an MSN 1-1 conversation C1
+          with a contact X can be moved to a representation as a nameless
+          chatroom, Cn, to which more contacts can be invited, by calling
+          <code>CreateChannel({...ChannelType: ...Text,
+            ...<tp:member-ref>InitialChannels</tp:member-ref>: [C1]})</code>
+          which returns Cn. C1 SHOULD remain open, with no underlying
+          switchboard attached. If X establishes a new switchboard with the
+          local user, C1 SHOULD pick up that switchboard rather than letting
+          it create a new channel.
+          <strong>[FIXME: should it?]</strong>
+          Similarly, if the local user sends a message in C1, then
+          a new switchboard to X should be created and associated with C1.</p>
+
+        <p>XMPP and MSN do not natively have a concept of merging two or more
+          channels C1, C2... into one channel, Cn. However, the GSM-style
+          merging API can be supported on XMPP and MSN, as an API short-cut
+          for upgrading C1 into a conference Cn (which invites the
+          TargetHandle of C1 into Cn), then immediately inviting the
+          TargetHandle of C2, the TargetHandle of C3, etc. into Cn as well.</p>
+
+        <p>With a suitable change of terminology, Skype has behaviour similar
+          to MSN.</p>
+      </tp:rationale>
+
+      <p>The <tp:dbus-ref
+          namespace="org.freedesktop.Telepathy.Channel.Interface"
+          >Group</tp:dbus-ref> MAY have channel-specific handles for participants;
+        clients SHOULD support both Conferences that have channel-specific handles,
+        and those that do not.</p>
+
+      <tp:rationale>
+        <p>In the GSM case, the Conference's Group interface MAY have
+          channel-specific handles, to reflect the fact that the identities of
+          the participants might not be known - it can be possible to know that
+          there is another participant in the Conference, but not know who
+          they are.
+          <strong>[FIXME: fact check from GSM gurus needed]</strong>
+        </p>
+
+        <p>In the XMPP case, the Conference's Group interface SHOULD have
+          channel-specific handles, to reflect the fact that the participants
+          have MUC-specific identities, and the user might also be able to see
+          their global identities, or not.</p>
+
+        <p>In most other cases, including MSN and link-local XMPP, the
+          Conference's Group interface SHOULD NOT have channel-specific
+          handles, since users' identities are always visible.</p>
+      </tp:rationale>
+
+      <p>Connection managers implementing channels with this interface
+        MUST NOT allow the object paths of channels that could be merged
+        into a Conference to be re-used, unless the channel re-using the
+        object path is equivalent to the channel that previously used it.</p>
+
+      <tp:rationale>
+        <p>If you upgrade some channels into a conference, and then close
+          the original channels, <tp:member-ref>InitialChannels</tp:member-ref>
+          (which is immutable) will contain paths to channels which no longer
+          exist. This implies that you should not re-use channel object paths,
+          unless future incarnations of the path are equivalent.</p>
+
+        <p>For instance, on protocols where you can only have
+          zero or one 1-1 text channels with Emily at one time, it would
+          be OK to re-use the same object path for every 1-1 text channel
+          with Emily; but on protocols where this is not true, it would
+          be misleading.</p>
+      </tp:rationale>
+
+    </tp:docstring>
+
+    <property name="Channels" tp:name-for-bindings="Channels"
+      access="read" type="ao">
+      <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+        <p>The individual <tp:dbus-ref
+            namespace="org.freedesktop.Telepathy">Channel</tp:dbus-ref>s that
+          are continued by this conference, which have the same <tp:dbus-ref
+              namespace="org.freedesktop.Telepathy.Channel"
+              >ChannelType</tp:dbus-ref> as this one, but with <tp:dbus-ref
+              namespace="org.freedesktop.Telepathy.Channel"
+              >TargetHandleType</tp:dbus-ref> = CONTACT.</p>
+
+        <p>This property MUST NOT be requestable.
+          <strong>[FIXME: or would it be better for this one, and not IC, to be
+            requestable?]</strong>
+        </p>
+
+        <p>Change notification is via the
+          <tp:member-ref>ChannelMerged</tp:member-ref> and
+          <tp:member-ref>ChannelRemoved</tp:member-ref> signals.</p>
+      </tp:docstring>
+    </property>
+
+    <signal name="ChannelMerged" tp:name-for-bindings="Channel_Merged">
+      <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+        <p>Emitted when a new channel is added to the value of
+          <tp:member-ref>Channels</tp:member-ref>.</p>
+      </tp:docstring>
+
+      <arg name="Channel" type="o">
+        <tp:docstring>The channel that was added to
+          <tp:member-ref>Channels</tp:member-ref>.</tp:docstring>
+      </arg>
+    </signal>
+
+    <signal name="ChannelRemoved" tp:name-for-bindings="Channel_Removed">
+      <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+        <p>Emitted when a channel is removed from the value of
+          <tp:member-ref>Channels</tp:member-ref>, either because it closed
+          or because it was split using the <tp:dbus-ref
+            namespace="org.freedesktop.Telepathy.Channel.Interface"
+            >Splittable.DRAFT.Split</tp:dbus-ref> method.</p>
+
+        <p><strong>[FIXME: relative ordering of this vs. Closed? Do we
+            care?]</strong></p>
+      </tp:docstring>
+
+      <arg name="Channel" type="o">
+        <tp:docstring>The channel that was removed from
+          <tp:member-ref>Channels</tp:member-ref>.</tp:docstring>
+      </arg>
+    </signal>
+
+    <property name="InitialChannels" tp:name-for-bindings="Initial_Channels"
+      access="read" type="ao">
+      <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+        <p>The initial value of <tp:member-ref>Channels</tp:member-ref>.</p>
+
+        <p>This property SHOULD be requestable. Omitting it from a request is
+          equivalent to providing it with an empty list as value. Requests
+          where its value has at least two elements SHOULD be expected to
+          succeed on any implementation of this interface.</p>
+
+        <p>Whether a request with 0 or 1 elements in the list will succeed is
+          indicated by <tp:member-ref>SupportsNonMerges</tp:member-ref>.</p>
+
+        <tp:rationale>
+          <p>In GSM, a pair of calls can be merged into a conference. In XMPP
+            and MSN, you can create a new chatroom, or upgrade one 1-1 channel
+            into a chatroom; however, on these protocols, it is also possible
+            to fake GSM-style merging by upgrading the first channel, then
+            inviting the targets of all the other channels into it.</p>
+        </tp:rationale>
+
+        <p>If possible, the <tp:member-ref>Channels</tp:member-ref>' states SHOULD
+          NOT be altered by merging them into a conference. However, depending on
+          the protocol, the Channels MAY be placed in a "frozen" state by placing
+          them in this property's value or by calling
+          <tp:dbus-ref
+            namespace="org.freedesktop.Telepathy.Channel.Interface"
+            >MergeableConference.DRAFT.Merge</tp:dbus-ref> on them.
+          <strong>[FIXME: there's nothing in RequestableChannelClasses yet
+            to say what will happen, see #24906 comment 6]</strong></p>
+
+        <tp:rationale>
+          <p>In Jingle, nothing special will happen to merged calls. UIs MAY
+            automatically place calls on hold before merging them, if that is
+            the desired behaviour; this SHOULD always work. Not doing
+            an implicit hold/unhold seems to preserve least-astonishment.</p>
+
+          <p><strong>[FIXME: check whether ring supports faking Hold on both
+              channels, as it probably should: see #24906 comment 6]</strong>
+          </p>
+
+          <p>In GSM, the calls that are merged go into a state similar to
+            Hold, but they cannot be unheld, only split from the conference
+            call using <tp:dbus-ref namespace="org.freedesktop.Telepathy"
+              >Channel.Interface.Splittable.DRAFT.Split</tp:dbus-ref>.</p>
+        </tp:rationale>
+
+        <p>Depending on the protocol, it might be signalled to remote users
+          that this channel is a continuation of all the requested channels,
+          or that it is only a continuation of the first channel in the
+          list.</p>
+
+        <tp:rationale>
+          <p>In MSN, the conference steals the underlying switchboard (protocol
+            construct) from one of its component channels, so the conference
+            appears to remote users to be a continuation of that channel and no
+            other. The connection manager has to make some arbitrary choice, so
+            we arbitrarily mandate that it SHOULD choose the first channel in
+            the list as the one to continue.</p>
+        </tp:rationale>
+
+        <p>This property is immutable.</p>
+      </tp:docstring>
+    </property>
+
+    <property name="InitialInviteeHandles"
+      tp:name-for-bindings="Initial_Invitee_Handles"
+      access="read" type="au" tp:type="Contact_Handle[]">
+      <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+        <p>A list of additional contacts invited to this conference when it
+          was created.</p>
+
+        <p>This property SHOULD be requestable, and appear in the allowed
+          properties in <tp:dbus-ref
+            namespace="org.freedesktop.Telepathy.Connection.Interface.Requests"
+            >RequestableChannelClasses</tp:dbus-ref>, in all connection
+          managers that can implement its semantics (in practice, this is
+          likely to mean exactly those connection managers where
+          <tp:member-ref>SupportsNonMerges</tp:member-ref> will be true).</p>
+
+        <p>If included in a request, the given contacts are automatically
+          invited into the new channel, as if they had been added with
+          <tp:dbus-ref namespace="org.freedesktop.Telepathy.Channel.Interface"
+            >Group.AddMembers</tp:dbus-ref>(InitialInviteeHandles,
+          <tp:member-ref>InvitationMessage</tp:member-ref> immediately after
+          the channel was created.</p>
+
+        <tp:rationale>
+          <p>This is a simple convenience API for the common case that a UI
+            upgrades a 1-1 chat to a multi-user chat solely in order to invite
+            someone else to participate.</p>
+        </tp:rationale>
+
+        <p>At most one of InitialInviteeHandles and InitialInviteeIDs may
+          appear in each request.</p>
+
+        <p>If the local user was not the initiator of this channel, the
+          <tp:dbus-ref namespace="org.freedesktop.Telepathy.Channel.Interface"
+            >Group.SelfHandle</tp:dbus-ref> SHOULD appear in the value of this
+          property, together with any other contacts invited at the same time
+          (if that information is known).</p>
+
+        <p>This property is immutable.</p>
+      </tp:docstring>
+    </property>
+
+    <property name="InitialInviteeIDs"
+      tp:name-for-bindings="Initial_Invitee_IDs"
+      access="read" type="as">
+      <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+        <p>A list of additional contacts invited to this conference when it
+          was created.</p>
+
+        <p>This property SHOULD be requestable, as an alternative to
+          <tp:member-ref>InitialInviteeHandles</tp:member-ref>. Its semantics
+          are the same, except that it takes a list of the string
+          representations of contact handles.</p>
+
+        <p>At most one of InitialInviteeHandles and InitialInviteeIDs may
+          appear in each request.</p>
+
+        <p>When a channel is created, the values of InitialInviteeHandles and
+          InitialInviteeIDs MUST correspond to each other.</p>
+
+        <p>This property is immutable.</p>
+      </tp:docstring>
+    </property>
+
+    <property name="InvitationMessage" tp:name-for-bindings="Invitation_Message"
+      access="read" type="s">
+      <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+        <p>The message that was sent to the
+          <tp:member-ref>InitialInviteeHandles</tp:member-ref> when they were
+          invited.</p>
+
+        <p>This property SHOULD be requestable, and appear in the allowed
+          properties in <tp:dbus-ref
+            namespace="org.freedesktop.Telepathy.Connection.Interface.Requests"
+            >RequestableChannelClasses</tp:dbus-ref>, in protocols where
+          invitations can have an accompanying text message.</p>
+
+        <tp:rationale>
+          <p>This allows invitations with a message to be sent when using
+            <tp:member-ref>InitialInviteeHandles</tp:member-ref> or
+            <tp:member-ref>InitialInviteeIDs</tp:member-ref>.</p>
+        </tp:rationale>
+
+        <p>If the local user was not the initiator of this channel, the
+          message with which they were invited (if any) SHOULD appear in the
+          value of this property.</p>
+
+        <p>This property is immutable.</p>
+      </tp:docstring>
+    </property>
+
+    <property name="SupportsNonMerges"
+      tp:name-for-bindings="Supports_Non_Merges"
+      access="read" type="b">
+      <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+        <p><strong>[FIXME: needs a better name; or perhaps it could be implied
+            by InitialInviteeHandles being requestable in XMPP/MSN but not in
+            GSM?]</strong></p>
+
+        <p>If true, requests with <tp:member-ref>InitialChannels</tp:member-ref>
+          omitted, empty, or one element long should be expected to succeed.</p>
+
+        <p>This property SHOULD appear in <tp:dbus-ref
+              namespace="org.freedesktop.Telepathy.Connection.Interface.Requests"
+              >RequestableChannelClasses</tp:dbus-ref> for
+          conference channels if and only if its value on those channels will
+          be true.</p>
+
+        <tp:rationale>
+          <p>Putting this in <tp:dbus-ref
+              namespace="org.freedesktop.Telepathy.Connection.Interface.Requests"
+              >RequestableChannelClasses</tp:dbus-ref> means clients can find
+            out whether their request will succeed early enough to do
+            something about it.</p>
+
+          <p>In XMPP, you can request a channel of type ROOM without
+            incorporating any 1-1 chats at all - indeed, this is the normal
+            way to do it - or as a continuation of a single 1-1 chat, and then
+            invite other people in later.</p>
+
+          <p>The sense of this property is a bit awkward, but it avoids making it
+            an anti-capability. If the sense were inverted, then its presence in
+            RequestableChannelClasses would imply that the protocol <em>lacks</em>
+            a feature; as it stands, it is additive. (Contrast with
+            <tp:dbus-ref
+              namespace="org.freedesktop.Telepathy.Channel.Type.StreamedMedia"
+              >ImmutableStreams</tp:dbus-ref>, which is the wrong way around for
+            backwards-compatibility reasons.)</p>
+        </tp:rationale>
+
+        <p>If false, <tp:member-ref>InitialChannels</tp:member-ref> SHOULD be
+          supplied in all requests for this channel class, and contain at least
+          two channels. Requests where this requirement is not met SHOULD fail
+          with NotImplemented.
+        </p>
+
+        <tp:rationale>
+          <p>In GSM, you can only make a conference call by merging at least
+            two channels.
+            <strong>[FIXME: the CM could conceivably fake it, but that would be
+              rather nasty]</strong>
+          </p>
+        </tp:rationale>
+      </tp:docstring>
+    </property>
+
+  </interface>
+</node>
diff --git a/extensions/misc.xml b/extensions/misc.xml
index 746cd90..6eea49a 100644
--- a/extensions/misc.xml
+++ b/extensions/misc.xml
@@ -7,5 +7,6 @@
 <xi:include href="Channel_Handler.xml"/>
 <xi:include href="Tube_Handler.xml"/>
 <xi:include href="Debug.xml" />
+<xi:include href="Channel_Interface_Conference.xml" />
 
 </tp:spec>
diff --git a/libempathy-gtk/empathy-contact-menu.c b/libempathy-gtk/empathy-contact-menu.c
index 4e1adfa..3d022a8 100644
--- a/libempathy-gtk/empathy-contact-menu.c
+++ b/libempathy-gtk/empathy-contact-menu.c
@@ -483,10 +483,7 @@ static void
 room_sub_menu_activate_cb (GtkWidget *item,
 			   RoomSubMenuData *data)
 {
-	TpHandle handle;
-	GArray handles = {(gchar *) &handle, 1};
 	EmpathyTpChat *chat;
-	TpChannel *channel;
 
 	chat = empathy_chatroom_get_tp_chat (data->chatroom);
 	if (chat == NULL) {
@@ -495,10 +492,8 @@ room_sub_menu_activate_cb (GtkWidget *item,
 	}
 
 	/* send invitation */
-	handle = empathy_contact_get_handle (data->contact);
-	channel = empathy_tp_chat_get_channel (chat);
-	tp_cli_channel_interface_group_call_add_members (channel, -1, &handles,
-		_("Inviting to this room"), NULL, NULL, NULL, NULL);
+	empathy_contact_list_add (EMPATHY_CONTACT_LIST (chat), data->contact,
+		_("Inviting you to this room"));
 }
 
 static GtkWidget *
diff --git a/libempathy-gtk/empathy-contact-selector-dialog.c b/libempathy-gtk/empathy-contact-selector-dialog.c
index 2793567..58e0fff 100644
--- a/libempathy-gtk/empathy-contact-selector-dialog.c
+++ b/libempathy-gtk/empathy-contact-selector-dialog.c
@@ -202,34 +202,6 @@ out:
 }
 
 static void
-contact_selector_dialog_response_cb (GtkWidget *widget,
-    gint response,
-    EmpathyContactSelectorDialog *dialog)
-{
-  EmpathyContactSelectorDialogPriv *priv = GET_PRIV (dialog);
-  TpConnection *connection;
-  const gchar *id;
-  EmpathyContactSelectorDialogClass *class = \
-    EMPATHY_CONTACT_SELECTOR_DIALOG_GET_CLASS (dialog);
-
-  connection = empathy_account_chooser_get_connection (
-    EMPATHY_ACCOUNT_CHOOSER (priv->account_chooser));
-  id = gtk_entry_get_text (GTK_ENTRY (priv->entry_id));
-  if (!connection || EMP_STR_EMPTY (id))
-    {
-      gtk_widget_destroy (widget);
-      return;
-    }
-
-  if (response == GTK_RESPONSE_ACCEPT)
-    {
-      class->got_response (dialog, connection, id);
-    }
-
-  gtk_widget_destroy (widget);
-}
-
-static void
 contact_selector_change_state_button_cb  (GtkEditable *editable,
     EmpathyContactSelectorDialog *dialog)
 {
@@ -331,9 +303,6 @@ empathy_contact_selector_dialog_init (EmpathyContactSelectorDialog *dialog)
   g_object_unref (completion);
   g_object_unref (model);
 
-  g_signal_connect (dialog, "response",
-        G_CALLBACK (contact_selector_dialog_response_cb), dialog);
-
   empathy_builder_connect (gui, dialog,
              "entry_id", "changed", contact_selector_change_state_button_cb,
              NULL);
@@ -341,6 +310,7 @@ empathy_contact_selector_dialog_init (EmpathyContactSelectorDialog *dialog)
   g_object_unref (gui);
 
   /* Create account chooser */
+  priv->show_account_chooser = TRUE;
   priv->account_chooser = empathy_account_chooser_new ();
   gtk_table_attach_defaults (GTK_TABLE (table_contact),
            priv->account_chooser,
@@ -434,6 +404,31 @@ empathy_contact_selector_dialog_class_init (
         G_PARAM_READWRITE));
 }
 
+const gchar *
+empathy_contact_selector_dialog_get_selected (
+    EmpathyContactSelectorDialog *self,
+    TpConnection **connection)
+{
+  EmpathyContactSelectorDialogPriv *priv;
+  const char *id;
+
+  g_return_val_if_fail (EMPATHY_IS_CONTACT_SELECTOR_DIALOG (self), NULL);
+
+  priv = GET_PRIV (self);
+
+  if (connection)
+    {
+      if (priv->show_account_chooser)
+        *connection = empathy_account_chooser_get_connection (
+            EMPATHY_ACCOUNT_CHOOSER (priv->account_chooser));
+      else
+        *connection = NULL;
+    }
+
+  id = gtk_entry_get_text (GTK_ENTRY (priv->entry_id));
+  return id;
+}
+
 void
 empathy_contact_selector_dialog_set_show_account_chooser (
     EmpathyContactSelectorDialog *self,
diff --git a/libempathy-gtk/empathy-contact-selector-dialog.h b/libempathy-gtk/empathy-contact-selector-dialog.h
index 255d37e..d8a698a 100644
--- a/libempathy-gtk/empathy-contact-selector-dialog.h
+++ b/libempathy-gtk/empathy-contact-selector-dialog.h
@@ -38,10 +38,6 @@ typedef struct _EmpathyContactSelectorDialogClass \
 struct _EmpathyContactSelectorDialogClass {
   GtkDialogClass parent_class;
 
-  void (*got_response) (EmpathyContactSelectorDialog *self,
-      TpConnection *connection,
-      const gchar *contact_id);
-
   gboolean (*account_filter) (EmpathyContactSelectorDialog *self,
       TpAccount *account);
 };
@@ -55,6 +51,9 @@ struct _EmpathyContactSelectorDialog {
 };
 
 GType empathy_contact_selector_dialog_get_type (void);
+const gchar *empathy_contact_selector_dialog_get_selected (
+    EmpathyContactSelectorDialog *self,
+    TpConnection **connection);
 void empathy_contact_selector_dialog_set_show_account_chooser (
     EmpathyContactSelectorDialog *self,
     gboolean show_account_chooser);
diff --git a/libempathy-gtk/empathy-new-call-dialog.c b/libempathy-gtk/empathy-new-call-dialog.c
index 2437b49..1a171af 100644
--- a/libempathy-gtk/empathy-new-call-dialog.c
+++ b/libempathy-gtk/empathy-new-call-dialog.c
@@ -90,13 +90,20 @@ got_contact_cb (EmpathyTpContactFactory *factory,
 }
 
 static void
-empathy_new_call_dialog_got_response (EmpathyContactSelectorDialog *dialog,
-    TpConnection *connection,
-    const gchar *contact_id)
+empathy_new_call_dialog_response (GtkDialog *dialog, int response_id)
 {
   EmpathyNewCallDialogPriv *priv = GET_PRIV (dialog);
   EmpathyTpContactFactory *factory;
   gboolean video;
+  TpConnection *connection;
+  const gchar *contact_id;
+
+  if (response_id != GTK_RESPONSE_ACCEPT) goto out;
+
+  contact_id = empathy_contact_selector_dialog_get_selected (
+      EMPATHY_CONTACT_SELECTOR_DIALOG (dialog), &connection);
+
+  if (EMP_STR_EMPTY (contact_id) || connection == NULL) goto out;
 
   /* check if video is enabled now because the dialog will be destroyed once
    * we return from this function. */
@@ -107,6 +114,9 @@ empathy_new_call_dialog_got_response (EmpathyContactSelectorDialog *dialog,
       got_contact_cb, GUINT_TO_POINTER (video), NULL, NULL);
 
   g_object_unref (factory);
+
+out:
+  gtk_widget_destroy (GTK_WIDGET (dialog));
 }
 
 static gboolean
@@ -204,15 +214,17 @@ empathy_new_call_dialog_class_init (
   EmpathyNewCallDialogClass *class)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (class);
-  EmpathyContactSelectorDialogClass *dialog_class = \
+  GtkDialogClass *dialog_class = GTK_DIALOG_CLASS (class);
+  EmpathyContactSelectorDialogClass *selector_dialog_class = \
     EMPATHY_CONTACT_SELECTOR_DIALOG_CLASS (class);
 
   g_type_class_add_private (class, sizeof (EmpathyNewCallDialogPriv));
 
   object_class->constructor = empathy_new_call_dialog_constructor;
 
-  dialog_class->got_response = empathy_new_call_dialog_got_response;
-  dialog_class->account_filter = empathy_new_call_dialog_account_filter;
+  dialog_class->response = empathy_new_call_dialog_response;
+
+  selector_dialog_class->account_filter = empathy_new_call_dialog_account_filter;
 }
 
 /**
diff --git a/libempathy-gtk/empathy-new-message-dialog.c b/libempathy-gtk/empathy-new-message-dialog.c
index 3b60b63..338da27 100644
--- a/libempathy-gtk/empathy-new-message-dialog.c
+++ b/libempathy-gtk/empathy-new-message-dialog.c
@@ -58,11 +58,22 @@ G_DEFINE_TYPE(EmpathyNewMessageDialog, empathy_new_message_dialog,
  */
 
 static void
-empathy_new_message_dialog_got_response (EmpathyContactSelectorDialog *dialog,
-    TpConnection *connection,
-    const gchar *contact_id)
+empathy_new_message_dialog_response (GtkDialog *dialog, int response_id)
 {
+  TpConnection *connection;
+  const gchar *contact_id;
+
+  if (response_id != GTK_RESPONSE_ACCEPT) goto out;
+
+  contact_id = empathy_contact_selector_dialog_get_selected (
+      EMPATHY_CONTACT_SELECTOR_DIALOG (dialog), &connection);
+
+  if (EMP_STR_EMPTY (contact_id) || connection == NULL) goto out;
+
   empathy_dispatcher_chat_with_contact_id (connection, contact_id, NULL, NULL);
+
+out:
+  gtk_widget_destroy (GTK_WIDGET (dialog));
 }
 
 static gboolean
@@ -151,13 +162,15 @@ empathy_new_message_dialog_class_init (
   EmpathyNewMessageDialogClass *class)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (class);
-  EmpathyContactSelectorDialogClass *dialog_class = \
+  GtkDialogClass *dialog_class = GTK_DIALOG_CLASS (class);
+  EmpathyContactSelectorDialogClass *selector_dialog_class = \
     EMPATHY_CONTACT_SELECTOR_DIALOG_CLASS (class);
 
   object_class->constructor = empathy_new_message_dialog_constructor;
 
-  dialog_class->got_response = empathy_new_message_dialog_got_response;
-  dialog_class->account_filter = empathy_new_message_account_filter;
+  dialog_class->response = empathy_new_message_dialog_response;
+
+  selector_dialog_class->account_filter = empathy_new_message_account_filter;
 }
 
 /**
diff --git a/libempathy/empathy-dispatcher.c b/libempathy/empathy-dispatcher.c
index 49be0ba..839daba 100644
--- a/libempathy/empathy-dispatcher.c
+++ b/libempathy/empathy-dispatcher.c
@@ -1610,6 +1610,19 @@ empathy_dispatcher_call_create_or_ensure_channel (
     }
 }
 
+/**
+ * empathy_dispatcher_create_channel:
+ * @self: the EmpathyDispatcher
+ * @connection: the Connection to dispatch on
+ * @request: an a{sv} map of properties for the request, i.e. using tp_asv_new()
+ * @callback: a callback for when the channel arrives (or NULL)
+ * @user_data: optional user data (or NULL)
+ *
+ * When calling this function, #EmpathyDispatcher takes ownership of your
+ * reference to @request. DO NOT unref or destroy @request. When the request is
+ * done, @request will be unreferenced. Take another reference if you want to
+ * keep it around.
+ */
 void
 empathy_dispatcher_create_channel (EmpathyDispatcher *self,
                                    TpConnection *connection,
diff --git a/libempathy/empathy-tp-chat.c b/libempathy/empathy-tp-chat.c
index e53caef..381095e 100644
--- a/libempathy/empathy-tp-chat.c
+++ b/libempathy/empathy-tp-chat.c
@@ -23,15 +23,15 @@
 
 #include <string.h>
 
-#include <telepathy-glib/channel.h>
-#include <telepathy-glib/dbus.h>
-#include <telepathy-glib/util.h>
-#include <telepathy-glib/interfaces.h>
+#include <telepathy-glib/telepathy-glib.h>
+
+#include <extensions/extensions.h>
 
 #include "empathy-tp-chat.h"
 #include "empathy-tp-contact-factory.h"
 #include "empathy-contact-monitor.h"
 #include "empathy-contact-list.h"
+#include "empathy-dispatcher.h"
 #include "empathy-marshal.h"
 #include "empathy-time.h"
 #include "empathy-utils.h"
@@ -60,6 +60,7 @@ typedef struct {
 	 * (channel doesn't implement the Password interface) */
 	gboolean               got_password_flags;
 	gboolean               ready;
+	gboolean               can_upgrade_to_muc;
 } EmpathyTpChatPriv;
 
 static void tp_chat_iface_init         (EmpathyContactListIface *iface);
@@ -117,17 +118,54 @@ tp_chat_add (EmpathyContactList *list,
 	     const gchar        *message)
 {
 	EmpathyTpChatPriv *priv = GET_PRIV (list);
-	TpHandle           handle;
-	GArray             handles = {(gchar *) &handle, 1};
 
-	g_return_if_fail (EMPATHY_IS_TP_CHAT (list));
-	g_return_if_fail (EMPATHY_IS_CONTACT (contact));
+	if (tp_proxy_has_interface_by_id (priv->channel,
+		TP_IFACE_QUARK_CHANNEL_INTERFACE_GROUP)) {
+		TpHandle           handle;
+		GArray             handles = {(gchar *) &handle, 1};
 
-	handle = empathy_contact_get_handle (contact);
-	tp_cli_channel_interface_group_call_add_members (priv->channel, -1,
-							 &handles, NULL,
-							 NULL, NULL, NULL,
-							 NULL);
+		g_return_if_fail (EMPATHY_IS_TP_CHAT (list));
+		g_return_if_fail (EMPATHY_IS_CONTACT (contact));
+
+		handle = empathy_contact_get_handle (contact);
+		tp_cli_channel_interface_group_call_add_members (priv->channel,
+			-1, &handles, NULL, NULL, NULL, NULL, NULL);
+	} else if (priv->can_upgrade_to_muc) {
+		EmpathyDispatcher *dispatcher;
+		TpConnection      *connection;
+		GHashTable        *props;
+		const char        *object_path;
+		GPtrArray          channels = { (gpointer *) &object_path, 1 };
+		const char        *invitees[2] = { NULL, };
+
+		dispatcher = empathy_dispatcher_dup_singleton ();
+		connection = tp_channel_borrow_connection (priv->channel);
+
+		invitees[0] = empathy_contact_get_id (contact);
+		object_path = tp_proxy_get_object_path (priv->channel);
+
+		props = tp_asv_new (
+		    TP_IFACE_CHANNEL ".ChannelType", G_TYPE_STRING,
+		        TP_IFACE_CHANNEL_TYPE_TEXT,
+		    TP_IFACE_CHANNEL ".TargetHandleType", G_TYPE_UINT,
+		        TP_HANDLE_TYPE_NONE,
+		    EMP_IFACE_CHANNEL_INTERFACE_CONFERENCE ".InitialChannels",
+		        TP_ARRAY_TYPE_OBJECT_PATH_LIST, &channels,
+		    EMP_IFACE_CHANNEL_INTERFACE_CONFERENCE ".InitialInviteeIDs",
+		        G_TYPE_STRV, invitees,
+		    /* FIXME: InvitationMessage ? */
+		    NULL);
+
+		/* Although this is a MUC, it's anonymous, so CreateChannel is
+		 * valid.
+		 * props now belongs to EmpathyDispatcher, don't free it */
+		empathy_dispatcher_create_channel (dispatcher, connection,
+				props, NULL, NULL);
+
+		g_object_unref (dispatcher);
+	} else {
+		g_warning ("Cannot add to this channel");
+	}
 }
 
 static void
@@ -1219,9 +1257,14 @@ tp_chat_constructor (GType                  type,
 			handles->len, (TpHandle *) handles->data,
 			tp_chat_got_added_contacts_cb, NULL, NULL, chat);
 
+		priv->can_upgrade_to_muc = FALSE;
+
 		g_signal_connect (priv->channel, "group-members-changed",
 			G_CALLBACK (tp_chat_group_members_changed_cb), chat);
 	} else {
+		EmpathyDispatcher *dispatcher = empathy_dispatcher_dup_singleton ();
+		GList *list, *ptr;
+
 		/* Get the self contact from the connection's self handle */
 		handle = tp_connection_get_self_handle (connection);
 		empathy_tp_contact_factory_get_from_handle (priv->factory,
@@ -1233,6 +1276,25 @@ tp_chat_constructor (GType                  type,
 		empathy_tp_contact_factory_get_from_handle (priv->factory,
 			handle, tp_chat_got_remote_contact_cb,
 			NULL, NULL, chat);
+
+		list = empathy_dispatcher_find_requestable_channel_classes (
+			dispatcher, connection,
+			tp_channel_get_channel_type (priv->channel),
+			TP_HANDLE_TYPE_ROOM, NULL);
+
+		for (ptr = list; ptr; ptr = ptr->next) {
+			GValueArray *array = ptr->data;
+			const char **oprops = g_value_get_boxed (
+				g_value_array_get_nth (array, 1));
+
+			if (tp_strv_contains (oprops, EMP_IFACE_CHANNEL_INTERFACE_CONFERENCE ".InitialChannels")) {
+				priv->can_upgrade_to_muc = TRUE;
+				break;
+			}
+		}
+
+		g_list_free (list);
+		g_object_unref (dispatcher);
 	}
 
 	if (tp_proxy_has_interface_by_id (priv->channel,
@@ -1714,3 +1776,24 @@ empathy_tp_chat_provide_password_finish (EmpathyTpChat *self,
 
 	return TRUE;
 }
+
+/**
+ * empathy_tp_chat_can_add_contact:
+ *
+ * Returns: %TRUE if empathy_contact_list_add() will work for this channel.
+ * That is if this chat is a 1-to-1 channel that can be upgraded to
+ * a MUC using the Conference interface or if the channel is a MUC.
+ */
+gboolean
+empathy_tp_chat_can_add_contact (EmpathyTpChat *self)
+{
+	EmpathyTpChatPriv *priv;
+
+	g_return_val_if_fail (EMPATHY_IS_TP_CHAT (self), FALSE);
+
+	priv = GET_PRIV (self);
+
+	return priv->can_upgrade_to_muc ||
+		tp_proxy_has_interface_by_id (priv->channel,
+			TP_IFACE_QUARK_CHANNEL_INTERFACE_GROUP);;
+}
diff --git a/libempathy/empathy-tp-chat.h b/libempathy/empathy-tp-chat.h
index 940c360..6b5fc8d 100644
--- a/libempathy/empathy-tp-chat.h
+++ b/libempathy/empathy-tp-chat.h
@@ -96,6 +96,7 @@ void           empathy_tp_chat_provide_password_async (EmpathyTpChat *chat,
 gboolean       empathy_tp_chat_provide_password_finish (EmpathyTpChat *chat,
 							GAsyncResult *result,
 							GError **error);
+gboolean       empathy_tp_chat_can_add_contact (EmpathyTpChat *self);
 
 G_END_DECLS
 
diff --git a/src/Makefile.am b/src/Makefile.am
index ecec892..3370f9b 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -44,6 +44,7 @@ empathy_handwritten_source = \
 	empathy-import-pidgin.c empathy-import-pidgin.h			\
 	empathy-import-utils.c empathy-import-utils.h			\
 	empathy-import-widget.c empathy-import-widget.h			\
+	empathy-invite-participant-dialog.c empathy-invite-participant-dialog.h \
 	empathy-main-window.c empathy-main-window.h			\
 	empathy-new-chatroom-dialog.c empathy-new-chatroom-dialog.h	\
 	empathy-preferences.c empathy-preferences.h			\
diff --git a/src/empathy-chat-window.c b/src/empathy-chat-window.c
index 658e594..6b0dc5d 100644
--- a/src/empathy-chat-window.c
+++ b/src/empathy-chat-window.c
@@ -35,14 +35,14 @@
 #include <glib/gi18n.h>
 #include <libnotify/notification.h>
 
-#include <telepathy-glib/account-manager.h>
-#include <telepathy-glib/util.h>
+#include <telepathy-glib/telepathy-glib.h>
 
 #include <libempathy/empathy-contact.h>
 #include <libempathy/empathy-message.h>
-#include <libempathy/empathy-dispatcher.h>
 #include <libempathy/empathy-chatroom-manager.h>
 #include <libempathy/empathy-utils.h>
+#include <libempathy/empathy-tp-contact-factory.h>
+#include <libempathy/empathy-contact-list.h>
 
 #include <libempathy-gtk/empathy-images.h>
 #include <libempathy-gtk/empathy-conf.h>
@@ -56,6 +56,7 @@
 
 #include "empathy-chat-window.h"
 #include "empathy-about-dialog.h"
+#include "empathy-invite-participant-dialog.h"
 
 #define DEBUG_FLAG EMPATHY_DEBUG_CHAT
 #include <libempathy/empathy-debug.h>
@@ -346,6 +347,32 @@ chat_window_menu_context_update (EmpathyChatWindowPriv *priv,
 }
 
 static void
+chat_window_conversation_menu_update (EmpathyChatWindowPriv *priv,
+                                      EmpathyChatWindow     *self)
+{
+	EmpathyTpChat *tp_chat;
+	TpConnection *connection;
+	GtkAction *action;
+	gboolean sensitive = FALSE;
+
+	g_return_if_fail (priv->current_chat != NULL);
+
+	action = gtk_ui_manager_get_action (priv->ui_manager,
+		"/chats_menubar/menu_conv/menu_conv_invite_participant");
+	tp_chat = empathy_chat_get_tp_chat (priv->current_chat);
+
+	if (tp_chat != NULL) {
+		connection = empathy_tp_chat_get_connection (tp_chat);
+
+		sensitive = empathy_tp_chat_can_add_contact (tp_chat) &&
+			(tp_connection_get_status (connection, NULL) ==
+			 TP_CONNECTION_STATUS_CONNECTED);
+	}
+
+	gtk_action_set_sensitive (action, sensitive);
+}
+
+static void
 chat_window_contact_menu_update (EmpathyChatWindowPriv *priv,
 				 EmpathyChatWindow     *window)
 {
@@ -536,6 +563,8 @@ chat_window_update (EmpathyChatWindow *window)
 	chat_window_menu_context_update (priv,
 					 num_pages);
 
+	chat_window_conversation_menu_update (priv, window);
+
 	chat_window_contact_menu_update (priv,
 					 window);
 
@@ -819,6 +848,71 @@ chat_window_contacts_toggled_cb (GtkToggleAction   *toggle_action,
 }
 
 static void
+got_contact_cb (EmpathyTpContactFactory *factory,
+                EmpathyContact          *contact,
+                const GError            *error,
+                gpointer                 user_data,
+                GObject                 *object)
+{
+	EmpathyTpChat *tp_chat = EMPATHY_TP_CHAT (user_data);
+
+	if (error != NULL) {
+		DEBUG ("Failed: %s", error->message);
+		return;
+	} else {
+		empathy_contact_list_add (EMPATHY_CONTACT_LIST (tp_chat),
+				contact, _("Inviting you to this room"));
+	}
+}
+
+static void
+chat_window_invite_participant_activate_cb (GtkAction         *action,
+					    EmpathyChatWindow *window)
+{
+	EmpathyChatWindowPriv *priv;
+	GtkWidget             *dialog;
+	EmpathyTpChat         *tp_chat;
+	TpChannel             *channel;
+	int                    response;
+
+	priv = GET_PRIV (window);
+
+	g_return_if_fail (priv->current_chat != NULL);
+
+	tp_chat = empathy_chat_get_tp_chat (priv->current_chat);
+	channel = empathy_tp_chat_get_channel (tp_chat);
+
+	/* FIXME: should filter out the existing participants from the
+	 * list */
+	dialog = empathy_invite_participant_dialog_new (
+			GTK_WINDOW (priv->dialog));
+	gtk_widget_show (dialog);
+
+	response = gtk_dialog_run (GTK_DIALOG (dialog));
+
+	if (response == GTK_RESPONSE_ACCEPT) {
+		TpConnection *connection;
+		EmpathyTpContactFactory *factory;
+		const char *id;
+
+		id = empathy_contact_selector_dialog_get_selected (
+				EMPATHY_CONTACT_SELECTOR_DIALOG (dialog), NULL);
+		if (EMP_STR_EMPTY (id)) goto out;
+
+		connection = tp_channel_borrow_connection (channel);
+		factory = empathy_tp_contact_factory_dup_singleton (connection);
+
+		empathy_tp_contact_factory_get_from_id (factory, id,
+			got_contact_cb, tp_chat,  NULL, NULL);
+
+		g_object_unref (factory);
+	}
+
+out:
+	gtk_widget_destroy (dialog);
+}
+
+static void
 chat_window_close_activate_cb (GtkAction         *action,
 			       EmpathyChatWindow *window)
 {
@@ -1725,6 +1819,7 @@ empathy_chat_window_init (EmpathyChatWindow *window)
 			      "menu_conv_clear", "activate", chat_window_clear_activate_cb,
 			      "menu_conv_favorite", "toggled", chat_window_favorite_toggled_cb,
 			      "menu_conv_toggle_contacts", "toggled", chat_window_contacts_toggled_cb,
+			      "menu_conv_invite_participant", "activate", chat_window_invite_participant_activate_cb,
 			      "menu_conv_close", "activate", chat_window_close_activate_cb,
 			      "menu_edit", "activate", chat_window_edit_activate_cb,
 			      "menu_edit_cut", "activate", chat_window_cut_activate_cb,
diff --git a/src/empathy-chat-window.ui b/src/empathy-chat-window.ui
index 57326a3..88d099c 100644
--- a/src/empathy-chat-window.ui
+++ b/src/empathy-chat-window.ui
@@ -39,6 +39,12 @@
           </object>
         </child>
         <child>
+          <object class="GtkAction" id="menu_conv_invite_participant">
+            <property name="name">menu_conv_invite_participant</property>
+            <property name="label" translatable="yes">Invite _Participant...</property>
+          </object>
+        </child>
+        <child>
           <object class="GtkAction" id="menu_conv_close">
             <property name="stock_id">gtk-close</property>
             <property name="name">menu_conv_close</property>
@@ -145,6 +151,7 @@
           <menuitem action="menu_conv_insert_smiley"/>
           <menuitem action="menu_conv_favorite"/>
           <menuitem action="menu_conv_toggle_contacts"/>
+          <menuitem action="menu_conv_invite_participant"/>
           <separator/>
           <menuitem action="menu_conv_close"/>
         </menu>
diff --git a/src/empathy-invite-participant-dialog.c b/src/empathy-invite-participant-dialog.c
new file mode 100644
index 0000000..f67a7fe
--- /dev/null
+++ b/src/empathy-invite-participant-dialog.c
@@ -0,0 +1,77 @@
+/*
+ * empathy-invite-participant-dialog.c
+ *
+ * EmpathyInviteParticipantDialog
+ *
+ * (c) 2009, Collabora Ltd.
+ *
+ * Authors:
+ *    Danielle Madeley <danielle.madeley@collabora.co.uk>
+ */
+
+#include <glib/gi18n.h>
+
+#include "empathy-invite-participant-dialog.h"
+
+#define GET_PRIVATE(obj)    (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EMPATHY_TYPE_INVITE_PARTICIPANT_DIALOG, EmpathyInviteParticipantDialogPrivate))
+
+G_DEFINE_TYPE (EmpathyInviteParticipantDialog,
+    empathy_invite_participant_dialog, EMPATHY_TYPE_CONTACT_SELECTOR_DIALOG);
+
+typedef struct _EmpathyInviteParticipantDialogPrivate EmpathyInviteParticipantDialogPrivate;
+struct _EmpathyInviteParticipantDialogPrivate
+{
+  int dum;
+};
+
+static void
+empathy_invite_participant_dialog_class_init (EmpathyInviteParticipantDialogClass *klass)
+{
+  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+  g_type_class_add_private (gobject_class, sizeof (EmpathyInviteParticipantDialogPrivate));
+}
+
+static void
+empathy_invite_participant_dialog_init (EmpathyInviteParticipantDialog *self)
+{
+  EmpathyContactSelectorDialog *parent = EMPATHY_CONTACT_SELECTOR_DIALOG (self);
+  // EmpathyInviteParticipantDialogPrivate *priv = GET_PRIVATE (self);
+  GtkWidget *label;
+  char *str;
+
+  label = gtk_label_new (NULL);
+  str = g_strdup_printf (
+      "<span size=\"x-large\" weight=\"bold\">%s</span>\n\n%s",
+      _("Invite Participant"),
+      _("Choose a contact to invite into the conversation:"));
+  gtk_label_set_markup (GTK_LABEL (label), str);
+  g_free (str);
+
+  gtk_box_pack_start (GTK_BOX (parent->vbox), label, FALSE, TRUE, 0);
+  /* move to the top -- wish there was a better way to do this */
+  gtk_box_reorder_child (GTK_BOX (parent->vbox), label, 0);
+  gtk_widget_show (label);
+
+  parent->button_action = gtk_dialog_add_button (GTK_DIALOG (self),
+      "Invite", GTK_RESPONSE_ACCEPT);
+  gtk_widget_set_sensitive (parent->button_action, FALSE);
+
+  gtk_window_set_title (GTK_WINDOW (self), _("Invite Participant"));
+  gtk_window_set_role (GTK_WINDOW (self), "invite_participant");
+  empathy_contact_selector_dialog_set_show_account_chooser (
+      EMPATHY_CONTACT_SELECTOR_DIALOG (self), FALSE);
+}
+
+GtkWidget *
+empathy_invite_participant_dialog_new (GtkWindow *parent)
+{
+  GtkWidget *self = g_object_new (EMPATHY_TYPE_INVITE_PARTICIPANT_DIALOG, NULL);
+
+  if (parent != NULL)
+    {
+      gtk_window_set_transient_for (GTK_WINDOW (self), parent);
+    }
+
+  return self;
+}
diff --git a/src/empathy-invite-participant-dialog.h b/src/empathy-invite-participant-dialog.h
new file mode 100644
index 0000000..561e107
--- /dev/null
+++ b/src/empathy-invite-participant-dialog.h
@@ -0,0 +1,46 @@
+/*
+ * empathy-invite-participant-dialog.h
+ *
+ * EmpathyInviteParticipantDialog
+ *
+ * (c) 2009, Collabora Ltd.
+ *
+ * Authors:
+ *    Danielle Madeley <danielle.madeley@collabora.co.uk>
+ */
+
+#ifndef __EMPATHY_INVITE_PARTICIPANT_DIALOG_H__
+#define __EMPATHY_INVITE_PARTICIPANT_DIALOG_H__
+
+#include <gtk/gtk.h>
+
+#include <libempathy-gtk/empathy-contact-selector-dialog.h>
+
+G_BEGIN_DECLS
+
+#define EMPATHY_TYPE_INVITE_PARTICIPANT_DIALOG	(empathy_invite_participant_dialog_get_type ())
+#define EMPATHY_INVITE_PARTICIPANT_DIALOG(obj)	(G_TYPE_CHECK_INSTANCE_CAST ((obj), EMPATHY_TYPE_INVITE_PARTICIPANT_DIALOG, EmpathyInviteParticipantDialog))
+#define EMPATHY_INVITE_PARTICIPANT_DIALOG_CLASS(obj)	(G_TYPE_CHECK_CLASS_CAST ((obj), EMPATHY_TYPE_INVITE_PARTICIPANT_DIALOG, EmpathyInviteParticipantDialogClass))
+#define EMPATHY_IS_INVITE_PARTICIPANT_DIALOG(obj)	(G_TYPE_CHECK_INSTANCE_TYPE ((obj), EMPATHY_TYPE_INVITE_PARTICIPANT_DIALOG))
+#define EMPATHY_IS_INVITE_PARTICIPANT_DIALOG_CLASS(obj)	(G_TYPE_CHECK_CLASS_TYPE ((obj), EMPATHY_TYPE_INVITE_PARTICIPANT_DIALOG))
+#define EMPATHY_INVITE_PARTICIPANT_DIALOG_GET_CLASS(obj)	(G_TYPE_INSTANCE_GET_CLASS ((obj), EMPATHY_TYPE_INVITE_PARTICIPANT_DIALOG, EmpathyInviteParticipantDialogClass))
+
+typedef struct _EmpathyInviteParticipantDialog EmpathyInviteParticipantDialog;
+typedef struct _EmpathyInviteParticipantDialogClass EmpathyInviteParticipantDialogClass;
+
+struct _EmpathyInviteParticipantDialog
+{
+  EmpathyContactSelectorDialog parent;
+};
+
+struct _EmpathyInviteParticipantDialogClass
+{
+  EmpathyContactSelectorDialogClass parent_class;
+};
+
+GType empathy_invite_participant_dialog_get_type (void);
+GtkWidget *empathy_invite_participant_dialog_new (GtkWindow *parent);
+
+G_END_DECLS
+
+#endif
