[Telepathy-commits] [telepathy-qt4/master] Moved TelepathyQt4/cli-* to TelepathyQt4/Client/.

Andre Moreira Magalhaes (andrunko) andre.magalhaes at collabora.co.uk
Mon Dec 29 12:01:01 PST 2008


---
 TelepathyQt4/Client/Account                        |    7 +
 TelepathyQt4/Client/AccountManager                 |    4 +-
 TelepathyQt4/Client/Channel                        |    3 +-
 TelepathyQt4/Client/Connection                     |    3 +-
 TelepathyQt4/Client/ConnectionManager              |    3 +-
 TelepathyQt4/Client/DBus                           |    3 +-
 TelepathyQt4/Client/DBusProxy                      |    7 +-
 TelepathyQt4/Client/MediaSessionHandler            |    3 +-
 TelepathyQt4/Client/MediaStreamHandler             |    3 +-
 TelepathyQt4/Client/OptionalInterfaceFactory       |    3 +-
 TelepathyQt4/Client/PendingChannel                 |    7 +
 TelepathyQt4/Client/PendingFailure                 |    3 +-
 TelepathyQt4/Client/PendingOperation               |    3 +-
 TelepathyQt4/Client/PendingSuccess                 |    2 +-
 TelepathyQt4/Client/PendingVoidMethodCall          |    3 +-
 TelepathyQt4/Client/Properties                     |    3 +-
 TelepathyQt4/Client/StatefulDBusProxy              |    7 +
 TelepathyQt4/Client/StatelessDBusProxy             |    7 +
 TelepathyQt4/Client/account-manager.cpp            |   25 +
 TelepathyQt4/Client/account-manager.h              |   45 +
 TelepathyQt4/Client/account.cpp                    |   25 +
 TelepathyQt4/Client/account.h                      |   41 +
 TelepathyQt4/Client/channel.cpp                    |  932 ++++++++++++++++++++
 TelepathyQt4/Client/channel.h                      |  819 +++++++++++++++++
 TelepathyQt4/Client/connection-manager.cpp         |  459 ++++++++++
 TelepathyQt4/Client/connection-manager.h           |  234 +++++
 TelepathyQt4/Client/connection.cpp                 |  502 +++++++++++
 TelepathyQt4/Client/connection.h                   |  476 ++++++++++
 TelepathyQt4/Client/dbus-proxy.cpp                 |   92 ++
 TelepathyQt4/Client/dbus-proxy.h                   |  190 ++++
 TelepathyQt4/Client/dbus.cpp                       |   25 +
 TelepathyQt4/Client/dbus.h                         |   49 +
 TelepathyQt4/Client/media-session-handler.cpp      |   25 +
 TelepathyQt4/Client/media-session-handler.h        |   45 +
 TelepathyQt4/Client/media-stream-handler.cpp       |   25 +
 TelepathyQt4/Client/media-stream-handler.h         |   45 +
 TelepathyQt4/Client/optional-interface-factory.cpp |   80 ++
 TelepathyQt4/Client/optional-interface-factory.h   |  122 +++
 TelepathyQt4/Client/pending-channel.cpp            |  110 +++
 TelepathyQt4/Client/pending-channel.h              |  136 +++
 TelepathyQt4/Client/pending-operation.cpp          |  189 ++++
 TelepathyQt4/Client/pending-operation.h            |  176 ++++
 TelepathyQt4/Client/properties.cpp                 |   25 +
 TelepathyQt4/Client/properties.h                   |   46 +
 TelepathyQt4/Client/simple-pending-operations.h    |  111 +++
 TelepathyQt4/Makefile.am                           |   76 +-
 TelepathyQt4/Prototype/Account.cpp                 |    1 +
 TelepathyQt4/cli-account-manager.cpp               |   25 -
 TelepathyQt4/cli-account-manager.h                 |   50 --
 TelepathyQt4/cli-account.cpp                       |   25 -
 TelepathyQt4/cli-account.h                         |   45 -
 TelepathyQt4/cli-channel.cpp                       |  931 -------------------
 TelepathyQt4/cli-channel.h                         |  826 -----------------
 TelepathyQt4/cli-connection-manager.cpp            |  460 ----------
 TelepathyQt4/cli-connection-manager.h              |  234 -----
 TelepathyQt4/cli-connection.cpp                    |  502 -----------
 TelepathyQt4/cli-connection.h                      |  472 ----------
 TelepathyQt4/cli-dbus-proxy.cpp                    |   93 --
 TelepathyQt4/cli-dbus-proxy.h                      |  190 ----
 TelepathyQt4/cli-dbus.cpp                          |   23 -
 TelepathyQt4/cli-dbus.h                            |   49 -
 TelepathyQt4/cli-media-session-handler.cpp         |   23 -
 TelepathyQt4/cli-media-session-handler.h           |   45 -
 TelepathyQt4/cli-media-stream-handler.cpp          |   23 -
 TelepathyQt4/cli-media-stream-handler.h            |   45 -
 TelepathyQt4/cli-optional-interface-factory.cpp    |   80 --
 TelepathyQt4/cli-optional-interface-factory.h      |  123 ---
 TelepathyQt4/cli-pending-channel.cpp               |  110 ---
 TelepathyQt4/cli-pending-channel.h                 |  137 ---
 TelepathyQt4/cli-pending-operation.cpp             |  190 ----
 TelepathyQt4/cli-pending-operation.h               |  176 ----
 TelepathyQt4/cli-properties.cpp                    |   23 -
 TelepathyQt4/cli-properties.h                      |   46 -
 TelepathyQt4/cli-simple-pending-operations.h       |  111 ---
 tests/prototype/prototype.cpp                      |    1 +
 75 files changed, 5145 insertions(+), 5113 deletions(-)
 create mode 100644 TelepathyQt4/Client/Account
 create mode 100644 TelepathyQt4/Client/PendingChannel
 create mode 100644 TelepathyQt4/Client/StatefulDBusProxy
 create mode 100644 TelepathyQt4/Client/StatelessDBusProxy
 create mode 100644 TelepathyQt4/Client/account-manager.cpp
 create mode 100644 TelepathyQt4/Client/account-manager.h
 create mode 100644 TelepathyQt4/Client/account.cpp
 create mode 100644 TelepathyQt4/Client/account.h
 create mode 100644 TelepathyQt4/Client/channel.cpp
 create mode 100644 TelepathyQt4/Client/channel.h
 create mode 100644 TelepathyQt4/Client/connection-manager.cpp
 create mode 100644 TelepathyQt4/Client/connection-manager.h
 create mode 100644 TelepathyQt4/Client/connection.cpp
 create mode 100644 TelepathyQt4/Client/connection.h
 create mode 100644 TelepathyQt4/Client/dbus-proxy.cpp
 create mode 100644 TelepathyQt4/Client/dbus-proxy.h
 create mode 100644 TelepathyQt4/Client/dbus.cpp
 create mode 100644 TelepathyQt4/Client/dbus.h
 create mode 100644 TelepathyQt4/Client/media-session-handler.cpp
 create mode 100644 TelepathyQt4/Client/media-session-handler.h
 create mode 100644 TelepathyQt4/Client/media-stream-handler.cpp
 create mode 100644 TelepathyQt4/Client/media-stream-handler.h
 create mode 100644 TelepathyQt4/Client/optional-interface-factory.cpp
 create mode 100644 TelepathyQt4/Client/optional-interface-factory.h
 create mode 100644 TelepathyQt4/Client/pending-channel.cpp
 create mode 100644 TelepathyQt4/Client/pending-channel.h
 create mode 100644 TelepathyQt4/Client/pending-operation.cpp
 create mode 100644 TelepathyQt4/Client/pending-operation.h
 create mode 100644 TelepathyQt4/Client/properties.cpp
 create mode 100644 TelepathyQt4/Client/properties.h
 create mode 100644 TelepathyQt4/Client/simple-pending-operations.h
 delete mode 100644 TelepathyQt4/cli-account-manager.cpp
 delete mode 100644 TelepathyQt4/cli-account-manager.h
 delete mode 100644 TelepathyQt4/cli-account.cpp
 delete mode 100644 TelepathyQt4/cli-account.h
 delete mode 100644 TelepathyQt4/cli-channel.cpp
 delete mode 100644 TelepathyQt4/cli-channel.h
 delete mode 100644 TelepathyQt4/cli-connection-manager.cpp
 delete mode 100644 TelepathyQt4/cli-connection-manager.h
 delete mode 100644 TelepathyQt4/cli-connection.cpp
 delete mode 100644 TelepathyQt4/cli-connection.h
 delete mode 100644 TelepathyQt4/cli-dbus-proxy.cpp
 delete mode 100644 TelepathyQt4/cli-dbus-proxy.h
 delete mode 100644 TelepathyQt4/cli-dbus.cpp
 delete mode 100644 TelepathyQt4/cli-dbus.h
 delete mode 100644 TelepathyQt4/cli-media-session-handler.cpp
 delete mode 100644 TelepathyQt4/cli-media-session-handler.h
 delete mode 100644 TelepathyQt4/cli-media-stream-handler.cpp
 delete mode 100644 TelepathyQt4/cli-media-stream-handler.h
 delete mode 100644 TelepathyQt4/cli-optional-interface-factory.cpp
 delete mode 100644 TelepathyQt4/cli-optional-interface-factory.h
 delete mode 100644 TelepathyQt4/cli-pending-channel.cpp
 delete mode 100644 TelepathyQt4/cli-pending-channel.h
 delete mode 100644 TelepathyQt4/cli-pending-operation.cpp
 delete mode 100644 TelepathyQt4/cli-pending-operation.h
 delete mode 100644 TelepathyQt4/cli-properties.cpp
 delete mode 100644 TelepathyQt4/cli-properties.h
 delete mode 100644 TelepathyQt4/cli-simple-pending-operations.h

diff --git a/TelepathyQt4/Client/Account b/TelepathyQt4/Client/Account
new file mode 100644
index 0000000..c5d2dbd
--- /dev/null
+++ b/TelepathyQt4/Client/Account
@@ -0,0 +1,7 @@
+#ifndef _TelepathyQt4_Client_Account_HEADER_GUARD_
+#define _TelepathyQt4_Client_Account_HEADER_GUARD_
+
+#include <TelepathyQt4/Client/account.h>
+
+#endif
+// vim:set ft=cpp:
diff --git a/TelepathyQt4/Client/AccountManager b/TelepathyQt4/Client/AccountManager
index ae99e7f..194e638 100644
--- a/TelepathyQt4/Client/AccountManager
+++ b/TelepathyQt4/Client/AccountManager
@@ -1,9 +1,7 @@
 #ifndef _TelepathyQt4_Client_AccountManager_HEADER_GUARD_
 #define _TelepathyQt4_Client_AccountManager_HEADER_GUARD_
 
-#include "TelepathyQt4/cli-account.h"
-
-#include "TelepathyQt4/cli-account-manager.h"
+#include <TelepathyQt4/Client/account-manager.h>
 
 #endif
 // vim:set ft=cpp:
diff --git a/TelepathyQt4/Client/Channel b/TelepathyQt4/Client/Channel
index f804921..b5ae6be 100644
--- a/TelepathyQt4/Client/Channel
+++ b/TelepathyQt4/Client/Channel
@@ -1,6 +1,7 @@
 #ifndef _TelepathyQt4_Client_Channel_HEADER_GUARD_
 #define _TelepathyQt4_Client_Channel_HEADER_GUARD_
 
-#include <TelepathyQt4/cli-channel.h>
+#include <TelepathyQt4/Client/channel.h>
 
 #endif
+// vim:set ft=cpp:
diff --git a/TelepathyQt4/Client/Connection b/TelepathyQt4/Client/Connection
index 6c22f58..b2f2ed7 100644
--- a/TelepathyQt4/Client/Connection
+++ b/TelepathyQt4/Client/Connection
@@ -1,6 +1,7 @@
 #ifndef _TelepathyQt4_Client_Connection_HEADER_GUARD_
 #define _TelepathyQt4_Client_Connection_HEADER_GUARD_
 
-#include <TelepathyQt4/cli-connection.h>
+#include <TelepathyQt4/Client/connection.h>
 
 #endif
+// vim:set ft=cpp:
diff --git a/TelepathyQt4/Client/ConnectionManager b/TelepathyQt4/Client/ConnectionManager
index 262aa8b..194bd29 100644
--- a/TelepathyQt4/Client/ConnectionManager
+++ b/TelepathyQt4/Client/ConnectionManager
@@ -1,6 +1,7 @@
 #ifndef _TelepathyQt4_Client_ConnectionManager_HEADER_GUARD_
 #define _TelepathyQt4_Client_ConnectionManager_HEADER_GUARD_
 
-#include <TelepathyQt4/cli-connection-manager.h>
+#include <TelepathyQt4/Client/connection-manager.h>
 
 #endif
+// vim:set ft=cpp:
diff --git a/TelepathyQt4/Client/DBus b/TelepathyQt4/Client/DBus
index 1b9ba3e..ac07383 100644
--- a/TelepathyQt4/Client/DBus
+++ b/TelepathyQt4/Client/DBus
@@ -1,6 +1,7 @@
 #ifndef _TelepathyQt4_Client_DBus_HEADER_GUARD_
 #define _TelepathyQt4_Client_DBus_HEADER_GUARD_
 
-#include <TelepathyQt4/cli-dbus.h>
+#include <TelepathyQt4/Client/dbus.h>
 
 #endif
+// vim:set ft=cpp:
diff --git a/TelepathyQt4/Client/DBusProxy b/TelepathyQt4/Client/DBusProxy
index d5b2c35..3b4fbd2 100644
--- a/TelepathyQt4/Client/DBusProxy
+++ b/TelepathyQt4/Client/DBusProxy
@@ -1,6 +1,7 @@
-#ifndef _TelepathyQt4_Client_DBus_Proxy_HEADER_GUARD_
-#define _TelepathyQt4_Client_DBus_Proxy_HEADER_GUARD_
+#ifndef _TelepathyQt4_Client_DBusProxy_HEADER_GUARD_
+#define _TelepathyQt4_Client_DBusProxy_HEADER_GUARD_
 
-#include <TelepathyQt4/cli-dbus-proxy.h>
+#include <TelepathyQt4/Client/dbus-proxy.h>
 
 #endif
+// vim:set ft=cpp:
diff --git a/TelepathyQt4/Client/MediaSessionHandler b/TelepathyQt4/Client/MediaSessionHandler
index c7fe9f2..5c82be0 100644
--- a/TelepathyQt4/Client/MediaSessionHandler
+++ b/TelepathyQt4/Client/MediaSessionHandler
@@ -1,6 +1,7 @@
 #ifndef _TelepathyQt4_Client_MediaSessionHandler_HEADER_GUARD_
 #define _TelepathyQt4_Client_MediaSessionHandler_HEADER_GUARD_
 
-#include <TelepathyQt4/cli-media-session-handler.h>
+#include <TelepathyQt4/Client/media-session-handler.h>
 
 #endif
+// vim:set ft=cpp:
diff --git a/TelepathyQt4/Client/MediaStreamHandler b/TelepathyQt4/Client/MediaStreamHandler
index edd1dd6..ec34640 100644
--- a/TelepathyQt4/Client/MediaStreamHandler
+++ b/TelepathyQt4/Client/MediaStreamHandler
@@ -1,6 +1,7 @@
 #ifndef _TelepathyQt4_Client_MediaStreamHandler_HEADER_GUARD_
 #define _TelepathyQt4_Client_MediaStreamHandler_HEADER_GUARD_
 
-#include <TelepathyQt4/cli-media-stream-handler.h>
+#include <TelepathyQt4/Client/media-stream-handler.h>
 
 #endif
+// vim:set ft=cpp:
diff --git a/TelepathyQt4/Client/OptionalInterfaceFactory b/TelepathyQt4/Client/OptionalInterfaceFactory
index 00c06e5..b8af12a 100644
--- a/TelepathyQt4/Client/OptionalInterfaceFactory
+++ b/TelepathyQt4/Client/OptionalInterfaceFactory
@@ -1,6 +1,7 @@
 #ifndef _TelepathyQt4_Client_OptionalInterfaceFactory_HEADER_GUARD_
 #define _TelepathyQt4_Client_OptionalInterfaceFactory_HEADER_GUARD_
 
-#include <TelepathyQt4/cli-optional-interface-factory.h>
+#include <TelepathyQt4/Client/optional-interface-factory.h>
 
 #endif
+// vim:set ft=cpp:
diff --git a/TelepathyQt4/Client/PendingChannel b/TelepathyQt4/Client/PendingChannel
new file mode 100644
index 0000000..cbb0c5e
--- /dev/null
+++ b/TelepathyQt4/Client/PendingChannel
@@ -0,0 +1,7 @@
+#ifndef _TelepathyQt4_Client_PendingChannel_HEADER_GUARD_
+#define _TelepathyQt4_Client_PendingChannel_HEADER_GUARD_
+
+#include <TelepathyQt4/Client/pending-channel.h>
+
+#endif
+// vim:set ft=cpp:
diff --git a/TelepathyQt4/Client/PendingFailure b/TelepathyQt4/Client/PendingFailure
index a49d428..8bd4233 100644
--- a/TelepathyQt4/Client/PendingFailure
+++ b/TelepathyQt4/Client/PendingFailure
@@ -1,8 +1,7 @@
 #ifndef _TelepathyQt4_Client_PendingFailure_HEADER_GUARD_
 #define _TelepathyQt4_Client_PendingFailure_HEADER_GUARD_
 
-#include <TelepathyQt4/cli-simple-pending-operations.h>
+#include <TelepathyQt4/Client/simple-pending-operations.h>
 
 #endif
 // vim:set ft=cpp:
-
diff --git a/TelepathyQt4/Client/PendingOperation b/TelepathyQt4/Client/PendingOperation
index 9ac8eba..34f704d 100644
--- a/TelepathyQt4/Client/PendingOperation
+++ b/TelepathyQt4/Client/PendingOperation
@@ -1,6 +1,7 @@
 #ifndef _TelepathyQt4_Client_PendingOperation_HEADER_GUARD_
 #define _TelepathyQt4_Client_PendingOperation_HEADER_GUARD_
 
-#include <TelepathyQt4/cli-pending-operation.h>
+#include <TelepathyQt4/Client/pending-operation.h>
 
 #endif
+// vim:set ft=cpp:
diff --git a/TelepathyQt4/Client/PendingSuccess b/TelepathyQt4/Client/PendingSuccess
index 8f9d66a..c62c89d 100644
--- a/TelepathyQt4/Client/PendingSuccess
+++ b/TelepathyQt4/Client/PendingSuccess
@@ -1,7 +1,7 @@
 #ifndef _TelepathyQt4_Client_PendingSuccess_HEADER_GUARD_
 #define _TelepathyQt4_Client_PendingSuccess_HEADER_GUARD_
 
-#include <TelepathyQt4/cli-simple-pending-operations.h>
+#include <TelepathyQt4/Client/simple-pending-operations.h>
 
 #endif
 // vim:set ft=cpp:
diff --git a/TelepathyQt4/Client/PendingVoidMethodCall b/TelepathyQt4/Client/PendingVoidMethodCall
index 9e3a183..f9f50e0 100644
--- a/TelepathyQt4/Client/PendingVoidMethodCall
+++ b/TelepathyQt4/Client/PendingVoidMethodCall
@@ -1,8 +1,7 @@
 #ifndef _TelepathyQt4_Client_PendingVoidMethodCall_HEADER_GUARD_
 #define _TelepathyQt4_Client_PendingVoidMethodCall_HEADER_GUARD_
 
-#include <TelepathyQt4/cli-simple-pending-operations.h>
+#include <TelepathyQt4/Client/simple-pending-operations.h>
 
 #endif
 // vim:set ft=cpp:
-
diff --git a/TelepathyQt4/Client/Properties b/TelepathyQt4/Client/Properties
index 788ba2a..3eb1bba 100644
--- a/TelepathyQt4/Client/Properties
+++ b/TelepathyQt4/Client/Properties
@@ -1,6 +1,7 @@
 #ifndef _TelepathyQt4_Client_Properties_HEADER_GUARD_
 #define _TelepathyQt4_Client_Properties_HEADER_GUARD_
 
-#include <TelepathyQt4/cli-properties.h>
+#include <TelepathyQt4/Client/properties.h>
 
 #endif
+// vim:set ft=cpp:
diff --git a/TelepathyQt4/Client/StatefulDBusProxy b/TelepathyQt4/Client/StatefulDBusProxy
new file mode 100644
index 0000000..5c81a50
--- /dev/null
+++ b/TelepathyQt4/Client/StatefulDBusProxy
@@ -0,0 +1,7 @@
+#ifndef _TelepathyQt4_Client_StatefulDBusProxy_HEADER_GUARD_
+#define _TelepathyQt4_Client_StatefulDBusProxy_HEADER_GUARD_
+
+#include <TelepathyQt4/Client/dbus-proxy.h>
+
+#endif
+// vim:set ft=cpp:
diff --git a/TelepathyQt4/Client/StatelessDBusProxy b/TelepathyQt4/Client/StatelessDBusProxy
new file mode 100644
index 0000000..e1093e6
--- /dev/null
+++ b/TelepathyQt4/Client/StatelessDBusProxy
@@ -0,0 +1,7 @@
+#ifndef _TelepathyQt4_Client_StatelessDBusProxy_HEADER_GUARD_
+#define _TelepathyQt4_Client_StatelessDBusProxy_HEADER_GUARD_
+
+#include <TelepathyQt4/Client/dbus-proxy.h>
+
+#endif
+// vim:set ft=cpp:
diff --git a/TelepathyQt4/Client/account-manager.cpp b/TelepathyQt4/Client/account-manager.cpp
new file mode 100644
index 0000000..3dd0231
--- /dev/null
+++ b/TelepathyQt4/Client/account-manager.cpp
@@ -0,0 +1,25 @@
+/*
+ * This file is part of TelepathyQt4
+ *
+ * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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 St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include "account-manager.h"
+
+#include <TelepathyQt4/_gen/cli-account-manager.moc.hpp>
+#include <TelepathyQt4/_gen/cli-account-manager-body.hpp>
diff --git a/TelepathyQt4/Client/account-manager.h b/TelepathyQt4/Client/account-manager.h
new file mode 100644
index 0000000..b82f997
--- /dev/null
+++ b/TelepathyQt4/Client/account-manager.h
@@ -0,0 +1,45 @@
+/*
+ * This file is part of TelepathyQt4
+ *
+ * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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 St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef _TelepathyQt4_cli_account_manager_h_HEADER_GUARD_
+#define _TelepathyQt4_cli_account_manager_h_HEADER_GUARD_
+
+/**
+ * \addtogroup clientsideproxies Client-side proxies
+ *
+ * Proxy objects representing remote service objects accessed via D-Bus.
+ *
+ * In addition to providing direct access to methods, signals and properties
+ * exported by the remote objects, some of these proxies offer features like
+ * automatic inspection of remote object capabilities, property tracking,
+ * backwards compatibility helpers for older services and other utilities.
+ */
+
+/**
+ * \defgroup clientaccount Account and Account Manager proxies
+ * \ingroup clientsideproxies
+ *
+ * ...
+ */
+
+#include <TelepathyQt4/_gen/cli-account-manager.h>
+
+#endif
diff --git a/TelepathyQt4/Client/account.cpp b/TelepathyQt4/Client/account.cpp
new file mode 100644
index 0000000..249931e
--- /dev/null
+++ b/TelepathyQt4/Client/account.cpp
@@ -0,0 +1,25 @@
+/*
+ * This file is part of TelepathyQt4
+ *
+ * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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 St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include "account.h"
+
+#include <TelepathyQt4/_gen/cli-account-body.hpp>
+#include <TelepathyQt4/_gen/cli-account.moc.hpp>
diff --git a/TelepathyQt4/Client/account.h b/TelepathyQt4/Client/account.h
new file mode 100644
index 0000000..20f149b
--- /dev/null
+++ b/TelepathyQt4/Client/account.h
@@ -0,0 +1,41 @@
+/*
+ * This file is part of TelepathyQt4
+ *
+ * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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 St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef _TelepathyQt4_cli_account_h_HEADER_GUARD_
+#define _TelepathyQt4_cli_account_h_HEADER_GUARD_
+
+/**
+ * \addtogroup clientsideproxies Client-side proxies
+ *
+ * Proxy objects representing remote service objects accessed via D-Bus.
+ *
+ * In addition to providing direct access to methods, signals and properties
+ * exported by the remote objects, some of these proxies offer features like
+ * automatic inspection of remote object capabilities, property tracking,
+ * backwards compatibility helpers for older services and other utilities.
+ */
+
+/* See account-manager.h for doxygen */
+
+#include <TelepathyQt4/_gen/cli-account.h>
+
+#endif
+
diff --git a/TelepathyQt4/Client/channel.cpp b/TelepathyQt4/Client/channel.cpp
new file mode 100644
index 0000000..320e277
--- /dev/null
+++ b/TelepathyQt4/Client/channel.cpp
@@ -0,0 +1,932 @@
+/*
+ * This file is part of TelepathyQt4
+ *
+ * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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 St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include "channel.h"
+#include "channel.moc.hpp"
+
+#include "dbus.h"
+
+#include <TelepathyQt4/_gen/cli-channel-body.hpp>
+#include <TelepathyQt4/_gen/cli-channel.moc.hpp>
+
+#include <TelepathyQt4/Constants>
+#include <TelepathyQt4/debug-internal.hpp>
+
+#include <QQueue>
+
+namespace Telepathy
+{
+namespace Client
+{
+
+struct Channel::Private
+{
+    // Public object
+    Channel& parent;
+
+    // Instance of generated interface class
+    ChannelInterface* baseInterface;
+
+    // Owning connection
+    Connection* connection;
+
+    // Optional interface proxies
+    ChannelInterfaceGroupInterface* group;
+    DBus::PropertiesInterface* properties;
+
+    // Introspection
+    Readiness readiness;
+    QStringList interfaces;
+    QQueue<void (Private::*)()> introspectQueue;
+
+    // Introspected properties
+
+    // Main interface
+    QString channelType;
+    uint targetHandleType;
+    uint targetHandle;
+
+    // Group flags
+    uint groupFlags;
+
+    // Group members
+    bool groupHaveMembers;
+    QSet<uint> groupMembers;
+    GroupMemberChangeInfoMap groupLocalPending;
+    QSet<uint> groupRemotePending;
+
+    // Group handle owners
+    bool groupAreHandleOwnersAvailable;
+    HandleOwnerMap groupHandleOwners;
+
+    // Group self handle
+    bool groupIsSelfHandleTracked;
+    uint groupSelfHandle;
+
+    // Group remove info
+    GroupMemberChangeInfo groupSelfRemoveInfo;
+
+    Private(Channel& parent, Connection* connection)
+        : parent(parent)
+    {
+        debug() << "Creating new Channel";
+
+        baseInterface = 0;
+        group = 0;
+        properties = 0;
+        readiness = ReadinessJustCreated;
+        targetHandleType = 0;
+        targetHandle = 0;
+
+        groupFlags = 0;
+        groupHaveMembers = false;
+        groupAreHandleOwnersAvailable = false;
+        groupIsSelfHandleTracked = false;
+        groupSelfHandle = 0;
+
+        debug() << " Connecting to Channel::Closed()";
+        parent.connect(baseInterface,
+                       SIGNAL(Closed()),
+                       SLOT(onClosed()));
+
+        debug() << " Connection to owning connection's lifetime signals";
+        parent.connect(connection,
+                       SIGNAL(readinessChanged(uint)),
+                       SLOT(onConnectionReadinessChanged(uint)));
+
+        parent.connect(connection,
+                       SIGNAL(destroyed()),
+                       SLOT(onConnectionDestroyed()));
+
+        if (connection->readiness() == Connection::ReadinessDead) {
+            warning() << "Connection given as the owner for a Channel was already dead! Channel will be stillborn.";
+            readiness = ReadinessDead;
+        }
+
+        introspectQueue.enqueue(&Private::introspectMain);
+    }
+
+    void introspectMain()
+    {
+        if (!properties) {
+            properties = parent.propertiesInterface();
+            Q_ASSERT(properties != 0);
+        }
+
+        debug() << "Calling Properties::GetAll(Channel)";
+        QDBusPendingCallWatcher* watcher =
+            new QDBusPendingCallWatcher(
+                    properties->GetAll(TELEPATHY_INTERFACE_CHANNEL), &parent);
+        parent.connect(watcher,
+                       SIGNAL(finished(QDBusPendingCallWatcher*)),
+                       SLOT(gotMainProperties(QDBusPendingCallWatcher*)));
+    }
+
+    void introspectMainFallbackChannelType()
+    {
+        debug() << "Calling Channel::GetChannelType()";
+        QDBusPendingCallWatcher* watcher =
+            new QDBusPendingCallWatcher(baseInterface->GetChannelType(), &parent);
+        parent.connect(watcher,
+                       SIGNAL(finished(QDBusPendingCallWatcher*)),
+                       SLOT(gotChannelType(QDBusPendingCallWatcher*)));
+    }
+
+    void introspectMainFallbackHandle()
+    {
+        debug() << "Calling Channel::GetHandle()";
+        QDBusPendingCallWatcher* watcher =
+            new QDBusPendingCallWatcher(baseInterface->GetHandle(), &parent);
+        parent.connect(watcher,
+                       SIGNAL(finished(QDBusPendingCallWatcher*)),
+                       SLOT(gotHandle(QDBusPendingCallWatcher*)));
+    }
+
+    void introspectMainFallbackInterfaces()
+    {
+        debug() << "Calling Channel::GetInterfaces()";
+        QDBusPendingCallWatcher* watcher =
+            new QDBusPendingCallWatcher(baseInterface->GetInterfaces(), &parent);
+        parent.connect(watcher,
+                       SIGNAL(finished(QDBusPendingCallWatcher*)),
+                       SLOT(gotInterfaces(QDBusPendingCallWatcher*)));
+    }
+
+    void introspectGroup()
+    {
+        Q_ASSERT(properties != 0);
+
+        if (!group) {
+            group = parent.groupInterface();
+            Q_ASSERT(group != 0);
+        }
+
+        debug() << "Connecting to Channel.Interface.Group::GroupFlagsChanged";
+        parent.connect(group,
+                       SIGNAL(GroupFlagsChanged(uint, uint)),
+                       SLOT(onGroupFlagsChanged(uint, uint)));
+
+        debug() << "Connecting to Channel.Interface.Group::MembersChanged";
+        parent.connect(group,
+                       SIGNAL(MembersChanged(const QString&, const Telepathy::UIntList&, const Telepathy::UIntList&, const Telepathy::UIntList&, const Telepathy::UIntList&, uint, uint)),
+                       SLOT(onMembersChanged(const QString&, const Telepathy::UIntList&, const Telepathy::UIntList&, const Telepathy::UIntList&, const Telepathy::UIntList&, uint, uint)));
+
+        debug() << "Connecting to Channel.Interface.Group::HandleOwnersChanged";
+        parent.connect(group,
+                       SIGNAL(HandleOwnersChanged(const Telepathy::HandleOwnerMap&, const Telepathy::UIntList&)),
+                       SLOT(onHandleOwnersChanged(const Telepathy::HandleOwnerMap&, const Telepathy::UIntList&)));
+
+        debug() << "Connecting to Channel.Interface.Group::SelfHandleChanged";
+        parent.connect(group,
+                       SIGNAL(SelfHandleChanged(uint)),
+                       SLOT(onSelfHandleChanged(uint)));
+
+        debug() << "Calling Properties::GetAll(Channel.Interface.Group)";
+        QDBusPendingCallWatcher* watcher =
+            new QDBusPendingCallWatcher(
+                    properties->GetAll(TELEPATHY_INTERFACE_CHANNEL_INTERFACE_GROUP), &parent);
+        parent.connect(watcher,
+                       SIGNAL(finished(QDBusPendingCallWatcher*)),
+                       SLOT(gotGroupProperties(QDBusPendingCallWatcher*)));
+    }
+
+    void introspectGroupFallbackFlags()
+    {
+        Q_ASSERT(group != 0);
+
+        debug() << "Calling Channel.Interface.Group::GetGroupFlags()";
+        QDBusPendingCallWatcher* watcher =
+            new QDBusPendingCallWatcher(group->GetGroupFlags(), &parent);
+        parent.connect(watcher,
+                       SIGNAL(finished(QDBusPendingCallWatcher*)),
+                       SLOT(gotGroupFlags(QDBusPendingCallWatcher*)));
+    }
+
+    void introspectGroupFallbackMembers()
+    {
+        Q_ASSERT(group != 0);
+
+        debug() << "Calling Channel.Interface.Group::GetAllMembers()";
+        QDBusPendingCallWatcher* watcher =
+            new QDBusPendingCallWatcher(group->GetAllMembers(), &parent);
+        parent.connect(watcher,
+                       SIGNAL(finished(QDBusPendingCallWatcher*)),
+                       SLOT(gotAllMembers(QDBusPendingCallWatcher*)));
+    }
+
+    void introspectGroupFallbackLocalPending()
+    {
+        Q_ASSERT(group != 0);
+
+        debug() << "Calling Channel.Interface.Group::GetLocalPendingMembersWithInfo()";
+        QDBusPendingCallWatcher* watcher =
+            new QDBusPendingCallWatcher(group->GetLocalPendingMembersWithInfo(), &parent);
+        parent.connect(watcher,
+                       SIGNAL(finished(QDBusPendingCallWatcher*)),
+                       SLOT(gotLocalPending(QDBusPendingCallWatcher*)));
+    }
+
+    void introspectGroupFallbackSelfHandle()
+    {
+        Q_ASSERT(group != 0);
+
+        debug() << "Calling Channel.Interface.Group::GetSelfHandle()";
+        QDBusPendingCallWatcher* watcher =
+            new QDBusPendingCallWatcher(group->GetSelfHandle(), &parent);
+        parent.connect(watcher,
+                       SIGNAL(finished(QDBusPendingCallWatcher*)),
+                       SLOT(gotSelfHandle(QDBusPendingCallWatcher*)));
+    }
+
+    void continueIntrospection()
+    {
+        if (readiness < ReadinessFull) {
+            if (introspectQueue.isEmpty()) {
+                changeReadiness(ReadinessFull);
+            } else {
+                (this->*introspectQueue.dequeue())();
+            }
+        }
+    }
+
+    void extract0177MainProps(const QVariantMap& props)
+    {
+        bool haveProps = props.size() >= 4
+                      && props.contains("ChannelType") && !qdbus_cast<QString>(props["ChannelType"]).isEmpty()
+                      && props.contains("Interfaces")
+                      && props.contains("TargetHandle")
+                      && props.contains("TargetHandleType");
+
+        if (!haveProps) {
+            warning() << " Properties specified in 0.17.7 not found";
+
+            introspectQueue.enqueue(&Private::introspectMainFallbackChannelType);
+            introspectQueue.enqueue(&Private::introspectMainFallbackHandle);
+            introspectQueue.enqueue(&Private::introspectMainFallbackInterfaces);
+        } else {
+            debug() << " Found properties specified in 0.17.7";
+
+            channelType = qdbus_cast<QString>(props["ChannelType"]);
+            interfaces = qdbus_cast<QStringList>(props["Interfaces"]);
+            targetHandle = qdbus_cast<uint>(props["TargetHandle"]);
+            targetHandleType = qdbus_cast<uint>(props["TargetHandleType"]);
+
+            nowHaveInterfaces();
+        }
+    }
+
+    void extract0176GroupProps(const QVariantMap& props)
+    {
+        bool haveProps = props.size() >= 6
+                      && (props.contains("GroupFlags") && (qdbus_cast<uint>(props["GroupFlags"]) & ChannelGroupFlagProperties))
+                      && props.contains("HandleOwners")
+                      && props.contains("LocalPendingMembers")
+                      && props.contains("Members")
+                      && props.contains("RemotePendingMembers")
+                      && props.contains("SelfHandle");
+
+        if (!haveProps) {
+            warning() << " Properties specified in 0.17.6 not found";
+            warning() << "  Handle owners and self handle tracking disabled";
+
+            introspectQueue.enqueue(&Private::introspectGroupFallbackFlags);
+            introspectQueue.enqueue(&Private::introspectGroupFallbackMembers);
+            introspectQueue.enqueue(&Private::introspectGroupFallbackLocalPending);
+            introspectQueue.enqueue(&Private::introspectGroupFallbackSelfHandle);
+        } else {
+            debug() << " Found properties specified in 0.17.6";
+
+            groupHaveMembers = true;
+            groupAreHandleOwnersAvailable = true;
+            groupIsSelfHandleTracked = true;
+
+            groupFlags = qdbus_cast<uint>(props["GroupFlags"]);
+            groupHandleOwners = qdbus_cast<HandleOwnerMap>(props["HandleOwners"]);
+            groupMembers = QSet<uint>::fromList(qdbus_cast<UIntList>(props["Members"]));
+            groupRemotePending = QSet<uint>::fromList(qdbus_cast<UIntList>(props["RemotePendingMembers"]));
+            groupSelfHandle = qdbus_cast<uint>(props["SelfHandle"]);
+
+            foreach (LocalPendingInfo info, qdbus_cast<LocalPendingInfoList>(props["LocalPendingMembers"])) {
+                groupLocalPending[info.toBeAdded] =
+                    GroupMemberChangeInfo(info.actor, info.reason, info.message);
+            }
+        }
+    }
+
+    void nowHaveInterfaces()
+    {
+        debug() << "Channel has" << interfaces.size() << "optional interfaces:" << interfaces;
+
+        for (QStringList::const_iterator i = interfaces.begin();
+                                         i != interfaces.end();
+                                         ++i) {
+            if (*i == TELEPATHY_INTERFACE_CHANNEL_INTERFACE_GROUP) {
+                introspectQueue.enqueue(&Private::introspectGroup);
+            }
+        }
+    }
+
+    void changeReadiness(Readiness newReadiness)
+    {
+        Q_ASSERT(newReadiness != readiness);
+        switch (readiness) {
+            case ReadinessJustCreated:
+                // We don't allow ReadinessClosed to be reached without ReadinessFull
+                // being reached at some point first.
+                Q_ASSERT((newReadiness == ReadinessFull) || (newReadiness == ReadinessDead));
+                break;
+            case ReadinessFull:
+                Q_ASSERT((newReadiness == ReadinessDead) || (newReadiness == ReadinessClosed));
+                break;
+            case ReadinessDead:
+            case ReadinessClosed:
+            default:
+                Q_ASSERT(false);
+                break;
+        }
+
+        debug() << "Channel readiness changed from" << readiness << "to" << newReadiness;
+
+        if (newReadiness == ReadinessFull) {
+            debug() << "Channel fully ready";
+            debug() << " Channel type" << channelType;
+            debug() << " Target handle" << targetHandle;
+            debug() << " Target handle type" << targetHandleType;
+
+            if (interfaces.contains(TELEPATHY_INTERFACE_CHANNEL_INTERFACE_GROUP)) {
+                debug() << " Group: flags" << groupFlags;
+                if (groupAreHandleOwnersAvailable)
+                    debug() << " Group: Number of handle owner mappings" << groupHandleOwners.size();
+                else
+                    debug() << " Group: No handle owners property present";
+                debug() << " Group: Number of current members" << groupMembers.size();
+                debug() << " Group: Number of local pending members" << groupLocalPending.size();
+                debug() << " Group: Number of remote pending members" << groupRemotePending.size();
+                debug() << " Group: Self handle" << groupSelfHandle << "tracked:" << (groupIsSelfHandleTracked ? "yes" : "no");
+            }
+        } else {
+            Q_ASSERT((newReadiness == ReadinessDead) || (newReadiness == ReadinessClosed));
+
+            debug() << "R.I.P. Channel.";
+
+            if (groupSelfRemoveInfo.isValid()) {
+                debug() << " Group: removed by  " << groupSelfRemoveInfo.actor();
+                debug() << "        because of  " << groupSelfRemoveInfo.reason();
+                debug() << "        with message" << groupSelfRemoveInfo.message();
+            }
+        }
+
+        readiness = newReadiness;
+        emit parent.readinessChanged(newReadiness);
+    }
+};
+
+Channel::Channel(Connection* connection,
+                 const QString& objectPath,
+                 QObject* parent)
+  : StatefulDBusProxy(connection->dbusConnection(), connection->busName(),
+            objectPath, parent),
+    mPriv(new Private(*this, connection))
+{
+    mPriv->baseInterface = new ChannelInterface(this->dbusConnection(),
+            this->busName(), this->objectPath(), this);
+
+    // Introspection continued here so mPriv will be initialized (unlike if we
+    // continued it from the Private constructor)
+    mPriv->continueIntrospection();
+}
+
+Channel::~Channel()
+{
+    delete mPriv;
+}
+
+Connection* Channel::connection() const
+{
+    return mPriv->connection;
+}
+
+Channel::Readiness Channel::readiness() const
+{
+    return mPriv->readiness;
+}
+
+QStringList Channel::interfaces() const
+{
+    // Different check than the others, because the optional interface getters
+    // may be used internally with the knowledge about getting the interfaces
+    // list, so we don't want this to cause warnings.
+    if (mPriv->readiness < ReadinessFull && mPriv->interfaces.empty())
+        warning() << "Channel::interfaces() used possibly before the list of interfaces has been received";
+    else if (mPriv->readiness == ReadinessDead)
+        warning() << "Channel::interfaces() used with readiness ReadinessDead";
+    else if (mPriv->readiness == ReadinessClosed)
+        warning() << "Channel::interfaces() used with readiness ReadinessClosed";
+
+    return mPriv->interfaces;
+}
+
+QString Channel::channelType() const
+{
+    // Similarly, we don't want warnings triggered when using the type interface
+    // proxies internally.
+    if (mPriv->readiness < ReadinessFull && mPriv->channelType.isEmpty())
+        warning() << "Channel::channelType() before the channel type has been received";
+    else if (mPriv->readiness == ReadinessDead)
+        warning() << "Channel::channelType() used with readiness ReadinessDead";
+    // Channel type will still be valid if the channel has been closed after
+    // introspection completed successfully.
+    // else if (mPriv->readiness == ReadinessClosed)
+    //    warning() << "Channel::channelType() used with readiness ReadinessClosed";
+
+    return mPriv->channelType;
+}
+
+uint Channel::targetHandleType() const
+{
+    if (mPriv->readiness != ReadinessFull)
+        warning() << "Channel::targetHandleType() used with readiness" << mPriv->readiness << "!= ReadinessFull";
+
+    return mPriv->targetHandleType;
+}
+
+uint Channel::targetHandle() const
+{
+    if (mPriv->readiness != ReadinessFull)
+        warning() << "Channel::targetHandle() used with readiness" << mPriv->readiness << "!= ReadinessFull";
+
+    return mPriv->targetHandle;
+}
+
+QDBusPendingReply<> Channel::close()
+{
+    // Closing a channel does not make sense if it is already dead or closed.
+    if ((mPriv->readiness != ReadinessDead) && (mPriv->readiness != ReadinessClosed))
+        return mPriv->baseInterface->Close();
+
+    // If the channel is in a readiness where it doesn't make sense to be
+    // closed, we emit a warning and return an error QDBusPendingReply.
+    warning() << "Channel::close() used with readiness" << mPriv->readiness;
+
+    return QDBusPendingReply<>(QDBusMessage::createError(
+            "TELEPATHY_ERROR_NOT_AVAILABLE", "Attempted to close an already dead or closed channel"));
+}
+
+uint Channel::groupFlags() const
+{
+    if (mPriv->readiness != ReadinessFull)
+        warning() << "Channel::groupFlags() used with readiness" << mPriv->readiness << "!= ReadinessFull";
+    else if (!mPriv->interfaces.contains(TELEPATHY_INTERFACE_CHANNEL_INTERFACE_GROUP))
+        warning() << "Channel::groupFlags() used with no group interface";
+
+    return mPriv->groupFlags;
+}
+
+QSet<uint> Channel::groupMembers() const
+{
+    if (mPriv->readiness != ReadinessFull)
+        warning() << "Channel::groupMembers() used with readiness" << mPriv->readiness << "!= ReadinessFull";
+    else if (!mPriv->interfaces.contains(TELEPATHY_INTERFACE_CHANNEL_INTERFACE_GROUP))
+        warning() << "Channel::groupMembers() used with no group interface";
+
+    return mPriv->groupMembers;
+}
+
+Channel::GroupMemberChangeInfoMap Channel::groupLocalPending() const
+{
+    if (mPriv->readiness != ReadinessFull)
+        warning() << "Channel::groupLocalPending() used with readiness" << mPriv->readiness << "!= ReadinessFull";
+    else if (!mPriv->interfaces.contains(TELEPATHY_INTERFACE_CHANNEL_INTERFACE_GROUP))
+        warning() << "Channel::groupLocalPending() used with no group interface";
+
+    return mPriv->groupLocalPending;
+}
+
+QSet<uint> Channel::groupRemotePending() const
+{
+    if (mPriv->readiness != ReadinessFull)
+        warning() << "Channel::groupRemotePending() used with readiness" << mPriv->readiness << "!= ReadinessFull";
+    else if (!mPriv->interfaces.contains(TELEPATHY_INTERFACE_CHANNEL_INTERFACE_GROUP))
+        warning() << "Channel::groupRemotePending() used with no group interface";
+
+    return mPriv->groupRemotePending;
+}
+
+bool Channel::groupAreHandleOwnersAvailable() const
+{
+    if (mPriv->readiness != ReadinessFull)
+        warning() << "Channel::groupAreHandleOwnersAvailable() used with readiness" << mPriv->readiness << "!= ReadinessFull";
+    else if (!mPriv->interfaces.contains(TELEPATHY_INTERFACE_CHANNEL_INTERFACE_GROUP))
+        warning() << "Channel::groupAreHandleOwnersAvailable() used with no group interface";
+
+    return mPriv->groupAreHandleOwnersAvailable;
+}
+
+HandleOwnerMap Channel::groupHandleOwners() const
+{
+    if (mPriv->readiness != ReadinessFull)
+        warning() << "Channel::groupHandleOwners() used with readiness" << mPriv->readiness << "!= ReadinessFull";
+    else if (!mPriv->interfaces.contains(TELEPATHY_INTERFACE_CHANNEL_INTERFACE_GROUP))
+        warning() << "Channel::groupAreHandleOwnersAvailable() used with no group interface";
+    else if (!groupAreHandleOwnersAvailable())
+        warning() << "Channel::areHandleOwnersAvailable() used, but handle owners not available";
+
+    return mPriv->groupHandleOwners;
+}
+
+bool Channel::groupIsSelfHandleTracked() const
+{
+    if (mPriv->readiness != ReadinessFull)
+        warning() << "Channel::isSelfHandleTracked() used with readiness" << mPriv->readiness << "!= ReadinessFull";
+    else if (!mPriv->interfaces.contains(TELEPATHY_INTERFACE_CHANNEL_INTERFACE_GROUP))
+        warning() << "Channel::groupIsSelfHandleTracked() used with no group interface";
+
+    return mPriv->groupIsSelfHandleTracked;
+}
+
+uint Channel::groupSelfHandle() const
+{
+    if (mPriv->readiness != ReadinessFull)
+        warning() << "Channel::groupSelfHandle() used with readiness" << mPriv->readiness << "!= ReadinessFull";
+    else if (!mPriv->interfaces.contains(TELEPATHY_INTERFACE_CHANNEL_INTERFACE_GROUP))
+        warning() << "Channel::groupSelfHandle() used with no group interface";
+
+    return mPriv->groupSelfHandle;
+}
+
+Channel::GroupMemberChangeInfo Channel::groupSelfRemoveInfo() const
+{
+    if (mPriv->readiness != ReadinessClosed)
+        warning() << "Channel::groupSelfRemoveInfo() used with readiness" << mPriv->readiness << "!= ReadinessClosed";
+    else if (!mPriv->interfaces.contains(TELEPATHY_INTERFACE_CHANNEL_INTERFACE_GROUP))
+        warning() << "Channel::groupSelfRemoveInfo() used with no group interface";
+
+    return mPriv->groupSelfRemoveInfo;
+}
+
+ChannelInterface* Channel::baseInterface() const
+{
+    return mPriv->baseInterface;
+}
+
+void Channel::gotMainProperties(QDBusPendingCallWatcher* watcher)
+{
+    QDBusPendingReply<QVariantMap> reply = *watcher;
+    QVariantMap props;
+
+    if (!reply.isError()) {
+        debug() << "Got reply to Properties::GetAll(Channel)";
+        props = reply.value();
+    } else {
+        warning().nospace() << "Properties::GetAll(Channel) failed with " << reply.error().name() << ": " << reply.error().message();
+    }
+
+    mPriv->extract0177MainProps(props);
+    // Add extraction (and possible fallbacks) in similar functions, called from here
+
+    mPriv->continueIntrospection();
+}
+
+void Channel::gotChannelType(QDBusPendingCallWatcher* watcher)
+{
+    QDBusPendingReply<QString> reply = *watcher;
+
+    if (reply.isError()) {
+        warning().nospace() << "Channel::GetChannelType() failed with " << reply.error().name() << ": " << reply.error().message() << ", Channel officially dead";
+        if ((mPriv->readiness != ReadinessDead) && (mPriv->readiness != ReadinessClosed))
+            mPriv->changeReadiness(ReadinessDead);
+        return;
+    }
+
+    debug() << "Got reply to fallback Channel::GetChannelType()";
+    mPriv->channelType = reply.value();
+    mPriv->continueIntrospection();
+}
+
+void Channel::gotHandle(QDBusPendingCallWatcher* watcher)
+{
+    QDBusPendingReply<uint, uint> reply = *watcher;
+
+    if (reply.isError()) {
+        warning().nospace() << "Channel::GetHandle() failed with " << reply.error().name() << ": " << reply.error().message() << ", Channel officially dead";
+        if ((mPriv->readiness != ReadinessDead) && (mPriv->readiness != ReadinessClosed))
+            mPriv->changeReadiness(ReadinessDead);
+        return;
+    }
+
+    debug() << "Got reply to fallback Channel::GetHandle()";
+    mPriv->targetHandleType = reply.argumentAt<0>();
+    mPriv->targetHandle = reply.argumentAt<1>();
+    mPriv->continueIntrospection();
+}
+
+void Channel::gotInterfaces(QDBusPendingCallWatcher* watcher)
+{
+    QDBusPendingReply<QStringList> reply = *watcher;
+
+    if (reply.isError()) {
+        warning().nospace() << "Channel::GetInterfaces() failed with " << reply.error().name() << ": " << reply.error().message() << ", Channel officially dead";
+        if ((mPriv->readiness != ReadinessDead) && (mPriv->readiness != ReadinessClosed))
+            mPriv->changeReadiness(ReadinessDead);
+        return;
+    }
+
+    debug() << "Got reply to fallback Channel::GetInterfaces()";
+    mPriv->interfaces = reply.value();
+    mPriv->nowHaveInterfaces();
+    mPriv->continueIntrospection();
+}
+
+void Channel::onClosed()
+{
+    debug() << "Got Channel::Closed";
+
+    if (mPriv->readiness == ReadinessFull)
+        mPriv->changeReadiness(ReadinessClosed);
+    else if ((mPriv->readiness != ReadinessDead) && (mPriv->readiness != ReadinessClosed))
+        mPriv->changeReadiness(ReadinessDead);
+}
+
+void Channel::onConnectionReadinessChanged(uint readiness)
+{
+    if (readiness == Connection::ReadinessDead && mPriv->readiness != ReadinessDead) {
+        debug() << "Owning connection died leaving an orphan Channel, changing to ReadinessDead";
+        mPriv->changeReadiness(ReadinessDead);
+    }
+}
+
+void Channel::onConnectionDestroyed()
+{
+    debug() << "Owning connection destroyed, cutting off dangling pointer";
+    mPriv->connection = 0;
+    return onConnectionReadinessChanged(Connection::ReadinessDead);
+}
+
+void Channel::gotGroupProperties(QDBusPendingCallWatcher* watcher)
+{
+    QDBusPendingReply<QVariantMap> reply = *watcher;
+    QVariantMap props;
+
+    if (!reply.isError()) {
+        debug() << "Got reply to Properties::GetAll(Channel.Interface.Group)";
+        props = reply.value();
+    } else {
+        warning().nospace() << "Properties::GetAll(Channel.Interface.Group) failed with " << reply.error().name() << ": " << reply.error().message();
+    }
+
+    mPriv->extract0176GroupProps(props);
+    // Add extraction (and possible fallbacks) in similar functions, called from here
+
+    mPriv->continueIntrospection();
+}
+
+void Channel::gotGroupFlags(QDBusPendingCallWatcher* watcher)
+{
+    QDBusPendingReply<uint> reply = *watcher;
+
+    if (reply.isError()) {
+        warning().nospace() << "Channel.Interface.Group::GetGroupFlags() failed with " << reply.error().name() << ": " << reply.error().message();
+    } else {
+        debug() << "Got reply to fallback Channel.Interface.Group::GetGroupFlags()";
+        mPriv->groupFlags = reply.value();
+
+        if (mPriv->groupFlags & ChannelGroupFlagProperties) {
+            warning() << " Reply included ChannelGroupFlagProperties, even though properties specified in 0.17.7 didn't work! - unsetting";
+            mPriv->groupFlags &= ~ChannelGroupFlagProperties;
+        }
+    }
+
+    mPriv->continueIntrospection();
+}
+
+void Channel::gotAllMembers(QDBusPendingCallWatcher* watcher)
+{
+    QDBusPendingReply<UIntList, UIntList, UIntList> reply = *watcher;
+
+    if (reply.isError()) {
+        warning().nospace() << "Channel.Interface.Group::GetAllMembers() failed with " << reply.error().name() << ": " << reply.error().message();
+    } else {
+        debug() << "Got reply to fallback Channel.Interface.Group::GetAllMembers()";
+
+        mPriv->groupHaveMembers = true;
+        mPriv->groupMembers = QSet<uint>::fromList(reply.argumentAt<0>());
+        mPriv->groupRemotePending = QSet<uint>::fromList(reply.argumentAt<2>());
+
+        foreach (uint handle, QSet<uint>::fromList(reply.argumentAt<1>())) {
+            mPriv->groupLocalPending[handle] = GroupMemberChangeInfo();
+        }
+    }
+
+    mPriv->continueIntrospection();
+}
+
+void Channel::gotLocalPending(QDBusPendingCallWatcher* watcher)
+{
+    QDBusPendingReply<LocalPendingInfoList> reply = *watcher;
+
+    if (reply.isError()) {
+        warning().nospace() << "Channel.Interface.Group::GetLocalPendingMembersWithInfo() failed with " << reply.error().name() << ": " << reply.error().message();
+        warning() << " Falling back to what GetAllMembers returned with no extended info";
+    } else {
+        debug() << "Got reply to fallback Channel.Interface.Group::GetLocalPendingMembersWithInfo()";
+
+        foreach (LocalPendingInfo info, reply.value()) {
+            mPriv->groupLocalPending[info.toBeAdded] =
+                GroupMemberChangeInfo(info.actor, info.reason, info.message);
+        }
+    }
+
+    mPriv->continueIntrospection();
+}
+
+void Channel::gotSelfHandle(QDBusPendingCallWatcher* watcher)
+{
+    QDBusPendingReply<uint> reply = *watcher;
+
+    if (reply.isError()) {
+        warning().nospace() << "Channel.Interface.Group::GetSelfHandle() failed with " << reply.error().name() << ": " << reply.error().message();
+    } else {
+        debug() << "Got reply to fallback Channel.Interface.Group::GetSelfHandle()";
+        mPriv->groupSelfHandle = reply.value();
+    }
+
+    mPriv->continueIntrospection();
+}
+
+void Channel::onGroupFlagsChanged(uint added, uint removed)
+{
+    debug().nospace() << "Got Channel.Interface.Group::GroupFlagsChanged(" << hex << added << ", " << removed << ")";
+
+    added &= ~(mPriv->groupFlags);
+    removed &= mPriv->groupFlags;
+
+    debug().nospace() << "Arguments after filtering (" << hex << added << ", " << removed << ")";
+
+    mPriv->groupFlags |= added;
+    mPriv->groupFlags &= ~removed;
+
+    if (added || removed) {
+        debug() << "Emitting groupFlagsChanged with" << mPriv->groupFlags << "value" << added << "added" << removed << "removed";
+        emit groupFlagsChanged(mPriv->groupFlags, added, removed);
+    }
+}
+
+void Channel::onMembersChanged(const QString& message, const Telepathy::UIntList& added, const Telepathy::UIntList& removed, const Telepathy::UIntList& localPending, const Telepathy::UIntList& remotePending, uint actor, uint reason)
+{
+    debug() << "Got Channel.Interface.Group::MembersChanged with" << added.size() << "added," << removed.size() << "removed," << localPending.size() << "moved to LP," << remotePending.size() << "moved to RP," << actor << " being the actor," << reason << "the reason and" << message << "the message";
+
+    if (!mPriv->groupHaveMembers) {
+        debug() << "Still waiting for initial group members, so ignoring delta signal...";
+        return;
+    }
+
+    UIntList currentAdded;
+    UIntList currentRemoved;
+    UIntList localAdded;
+    UIntList localRemoved;
+    UIntList remoteAdded;
+    UIntList remoteRemoved;
+
+    foreach (uint handle, added) {
+        if (!mPriv->groupMembers.contains(handle)) {
+            debug() << " +++" << handle;
+            mPriv->groupMembers.insert(handle);
+            currentAdded.append(handle);
+        }
+    }
+
+    foreach (uint handle, localPending) {
+        GroupMemberChangeInfo info(actor, reason, message);
+
+        // Special-case renaming a local-pending contact, if the signal is
+        // spec-compliant. Keep the old extended info in this case.
+        if (reason == ChannelGroupChangeReasonRenamed
+                && added.size() == 0
+                && localPending.size() == 1
+                && remotePending.size() == 0
+                && removed.size() == 1
+                && mPriv->groupLocalPending.contains(removed[0])) {
+            debug() << " Special-case local pending rename" << removed[0] << " -> " << handle;
+            info = mPriv->groupLocalPending[removed[0]];
+        }
+
+        if (!mPriv->groupLocalPending.contains(handle)) {
+            debug() << " LP" << handle;
+            mPriv->groupLocalPending[handle] = info;
+            localAdded.append(handle);
+        }
+    }
+
+    foreach (uint handle, remotePending) {
+        if (!mPriv->groupRemotePending.contains(handle)) {
+            debug() << " RP" << handle;
+            mPriv->groupRemotePending.insert(handle);
+            remoteAdded.append(handle);
+        }
+    }
+
+    foreach (uint handle, removed) {
+        debug() << " ---" << handle;
+
+        if (mPriv->groupMembers.remove(handle))
+            currentRemoved.append(handle);
+
+        if (mPriv->groupLocalPending.remove(handle))
+            localRemoved.append(handle);
+
+        if (mPriv->groupRemotePending.remove(handle))
+            remoteRemoved.append(handle);
+
+        if (handle == mPriv->groupSelfHandle) {
+            debug() << " Self handle removed, saving info...";
+            mPriv->groupSelfRemoveInfo = GroupMemberChangeInfo(actor, reason, message);
+        }
+    }
+
+    if (currentAdded.size() || currentRemoved.size()) {
+        debug() << " Emitting groupMembersChanged with" << currentAdded.size() << "contacts added and" << currentRemoved.size() << "contacts removed";
+        emit groupMembersChanged(mPriv->groupMembers, currentAdded, currentRemoved, actor, reason, message);
+    }
+
+    if (localAdded.size() || localRemoved.size()) {
+        debug() << " Emitting groupLocalPendingChanged with" << localAdded.size() << "contacts added and" << localRemoved.size() << "contacts removed";
+        emit groupLocalPendingChanged(mPriv->groupLocalPending, localAdded, localRemoved, actor, reason, message);
+    }
+
+    if (remoteAdded.size() || remoteRemoved.size()) {
+        debug() << " Emitting groupRemotePendingChanged with" << remoteAdded.size() << "contacts added and" << remoteRemoved.size() << "contacts removed";
+        emit groupMembersChanged(mPriv->groupRemotePending, remoteAdded, remoteRemoved, actor, reason, message);
+    }
+}
+
+void Channel::onHandleOwnersChanged(const Telepathy::HandleOwnerMap& added, const Telepathy::UIntList& removed)
+{
+    debug() << "Got Channel.Interface.Group::HandleOwnersChanged with" << added.size() << "added," << removed.size() << "removed";
+
+    if (!mPriv->groupAreHandleOwnersAvailable) {
+        debug() << "Still waiting for initial handle owners, so ignoring delta signal...";
+        return;
+    }
+
+    UIntList emitAdded;
+    UIntList emitRemoved;
+
+    for (HandleOwnerMap::const_iterator i = added.begin();
+                                        i != added.end();
+                                        ++i) {
+        uint handle = i.key();
+        uint global = i.value();
+
+        if (!mPriv->groupHandleOwners.contains(handle)
+                || mPriv->groupHandleOwners[handle] != global) {
+            debug() << " +++/changed" << handle << "->" << global;
+            mPriv->groupHandleOwners[handle] = global;
+            emitAdded.append(handle);
+        }
+    }
+
+    foreach (uint handle, removed) {
+        if (mPriv->groupHandleOwners.contains(handle)) {
+            debug() << " ---" << handle;
+            mPriv->groupHandleOwners.remove(handle);
+            emitRemoved.append(handle);
+        }
+    }
+
+    if (emitAdded.size() || emitRemoved.size()) {
+        debug() << "Emitting groupHandleOwnersChanged with" << emitAdded.size() << "added" << emitRemoved.size() << "removed";
+        emit groupHandleOwnersChanged(mPriv->groupHandleOwners, emitAdded, emitRemoved);
+    }
+}
+
+void Channel::onSelfHandleChanged(uint newSelfHandle)
+{
+    debug().nospace() << "Got Channel.Interface.Group::SelfHandleChanged";
+
+    if (newSelfHandle != mPriv->groupSelfHandle) {
+        mPriv->groupSelfHandle = newSelfHandle;
+        debug() << " Emitting groupSelfHandleChanged with new self handle" << newSelfHandle;
+        emit groupSelfHandleChanged(newSelfHandle);
+    }
+}
+
+}
+}
diff --git a/TelepathyQt4/Client/channel.h b/TelepathyQt4/Client/channel.h
new file mode 100644
index 0000000..c4ae5c9
--- /dev/null
+++ b/TelepathyQt4/Client/channel.h
@@ -0,0 +1,819 @@
+/*
+ * This file is part of TelepathyQt4
+ *
+ * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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 St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef _TelepathyQt4_cli_channel_h_HEADER_GUARD_
+#define _TelepathyQt4_cli_channel_h_HEADER_GUARD_
+
+/**
+ * \addtogroup clientsideproxies Client-side proxies
+ *
+ * Proxy objects representing remote service objects accessed via D-Bus.
+ *
+ * In addition to providing direct access to methods, signals and properties
+ * exported by the remote objects, some of these proxies offer features like
+ * automatic inspection of remote object capabilities, property tracking,
+ * backwards compatibility helpers for older services and other utilities.
+ */
+
+/**
+ * \defgroup clientchannel Channel proxies
+ * \ingroup clientsideproxies
+ *
+ * Proxy objects representing remote Telepathy Channels and their optional
+ * interfaces.
+ */
+
+#include <TelepathyQt4/_gen/cli-channel.h>
+
+#include <TelepathyQt4/Client/Connection>
+#include <TelepathyQt4/Client/DBus>
+#include <TelepathyQt4/Client/DBusProxy>
+#include <TelepathyQt4/Client/OptionalInterfaceFactory>
+
+#include <QSet>
+#include <QDBusPendingCallWatcher>
+
+namespace Telepathy
+{
+namespace Client
+{
+
+/**
+ * \class Channel
+ * \ingroup clientchannel
+ * \headerfile TelepathyQt4/Client/channel.h <TelepathyQt4/Client/Channel>
+ *
+ * High-level proxy object for accessing remote %Telepathy %Channel objects.
+ *
+ * It adds the following features compared to using ChannelInterface directly:
+ * <ul>
+ *  <li>Life cycle tracking</li>
+ *  <li>Getting the channel type, handle type, handle and interfaces automatically</li>
+ *  <li>Shared optional interface proxy instances</li>
+ * </ul>
+ *
+ * The remote object state accessor functions on this object (interfaces(),
+ * channelType(), targetHandleType(), targetHandle()) don't make any DBus calls;
+ * instead, they return values cached from a previous introspection run. The
+ * introspection process populates their values in the most efficient way
+ * possible based on what the service implements. However, their value is not
+ * defined unless the object has readiness #ReadinessFull, as returned by
+ * readiness() and indicated by emissions of the readinessChanged() signal.
+ *
+ * Additionally, the state of the Group interface on the remote object (if
+ * present) will be cached in the introspection process, and also tracked for
+ * any changes.
+ *
+ * Each Channel is owned by a Connection. If the Connection becomes dead (as
+ * signaled by Connection::readinessChanged) or is deleted, the Channel object
+ * will transition to ReadinessDead too.
+ */
+class Channel : public StatefulDBusProxy, private OptionalInterfaceFactory
+{
+    Q_OBJECT
+    Q_ENUMS(Readiness)
+
+public:
+    /**
+     * Describes readiness of the Channel for usage. The readiness depends on
+     * the state of the remote object. In suitable states, an asynchronous
+     * introspection process is started, and the Channel becomes more ready when
+     * that process is completed.
+     */
+    enum Readiness {
+        /**
+         * The object has just been created and introspection is still in
+         * progress. No functionality dependent on introspection is available.
+         *
+         * The readiness can change to any other state except ReadinessClosed
+         * depending on the result of the initial state query to the remote
+         * object.
+         */
+        ReadinessJustCreated = 0,
+
+        /**
+         * The remote object is alive and all introspection has been completed.
+         * Most functionality is available.
+         *
+         * The readiness can change to ReadinessDead or ReadinessClosed.
+         */
+        ReadinessFull = 5,
+
+        /**
+         * The remote object has gone into a state where it can no longer be
+         * used in an unexpected way. No functionality is available.
+         *
+         * No further readiness changes are possible.
+         */
+        ReadinessDead = 10,
+
+        /**
+         * The remote object has been closed and so can no longer be used.
+         * No functionality is available.
+         *
+         * No further readiness changes are possible.
+         */
+        ReadinessClosed = 15,
+
+        _ReadinessInvalid = 0xffff
+    };
+
+    /**
+     * Creates a Channel associated with the given object on the same service as
+     * the given connection.
+     *
+     * \param connection  Connection owning this Channel, and specifying the
+     *                    service.
+     * \param objectPath  Path to the object on the service.
+     * \param parent      Passed to the parent class constructor.
+     */
+    Channel(Connection* connection,
+            const QString& objectPath,
+            QObject* parent = 0);
+
+    /**
+     * Class destructor.
+     */
+    ~Channel();
+
+    /**
+     * Returns the owning Connection of the Channel.
+     *
+     * \return Pointer to the Connection.
+     */
+    Connection* connection() const;
+
+    /**
+     * Returns the current readiness of the Channel.
+     *
+     * \return The readiness, as defined in #Readiness.
+     */
+    Readiness readiness() const;
+
+    /**
+     * Returns a list of optional interfaces implemented by the remote object.
+     *
+     * \return D-Bus names of the implemented optional interfaces.
+     */
+    QStringList interfaces() const;
+
+    /**
+     * Returns the type of this channel.
+     *
+     * \return D-Bus interface name for the type of the channel.
+     */
+    QString channelType() const;
+
+    /**
+     * Returns the type of the handle returned by #targetHandle().
+     *
+     * \return The type of the handle, as specified in #HandleType.
+     */
+    uint targetHandleType() const;
+
+    /**
+     * Returns the handle of the remote party with which this channel
+     * communicates.
+     *
+     * \return The handle, which is of the type #targetHandleType() indicates.
+     */
+    uint targetHandle() const;
+
+public Q_SLOTS:
+    /**
+     * Close the channel.
+     *
+     * When this method is used as a slot, it is fire-and-forget. If you want
+     * to know if an error occurs when closing the channel, then you should
+     * use the returned object.
+     *
+     * A channel can be closed if its Readiness is ReadinessJustCreated or
+     * ReadinessFull. It cannot be closed if its Readiness is ReadinessDead or
+     * ReadinessClosed. If this method is called on a channel which is already
+     * in either the ReadinessDead or ReadinessClosed state, a DBus error of type
+     * TELEPATHY_ERROR_NOT_AVAILABLE will be returned.
+     *
+     * If the introspection of a channel is not complete (ReadinessJustCreated)
+     * when close() is called, the channel readiness will change to ReadinessDead
+     * instead of ReadinessClosed, which results if the channel is closed after
+     * the introspection is complete (ReadinessFull).
+     *
+     * \return QDBusPendingReply object for the call to Close() on the Channel
+     *         interface.
+     */
+    QDBusPendingReply<> close();
+
+Q_SIGNALS:
+    /**
+     * Emitted whenever the readiness of the Channel changes. When the channel
+     * is closed, this signal will be emitted with readiness #ReadinessClosed.
+     *
+     * \param newReadiness The new readiness, as defined in #Readiness.
+     */
+    void readinessChanged(uint newReadiness);
+
+    /**
+     * \name Group interface
+     *
+     * Cached access to state of the group interface on the associated remote
+     * object, if the interface is present. All methods return undefined values
+     * if the list returned by interfaces() doesn't include
+     * #TELEPATHY_INTERFACE_CHANNEL_INTERFACE_GROUP or if the object doesn't have
+     * readiness #ReadinessFull.
+     *
+     * As the Group interface state can change freely during the lifetime of the
+     * group due to events like new contacts joining the group, the cached state
+     * is automatically kept in sync with the remote object's state by hooking
+     * to the change notification signals present in the D-Bus interface.
+     *
+     * As the cached value changes, change notification signals are emitted.
+     * However, the value being initially discovered by introspection is still
+     * signaled by a readiness change to #ReadinessFull.
+     *
+     * There is a change notification signal &lt;attribute&gt;Changed
+     * corresponding to each cached attribute. The first parameter for each of
+     * these signals is the new value of the attribute, which is suited for
+     * displaying the value of the attribute in a widget in a model-view
+     * fashion. The remaining arguments depend on the attribute, but in general
+     * include at least the delta from the previous state of the attribute to
+     * the new state.
+     *
+     * Check the individual signals' descriptions for details.
+     */
+    //@{
+
+public:
+
+    /**
+     * Returns a set of flags indicating the capabilities and behaviour of the
+     * group represented by the remote object.
+     *
+     * Change notification is via groupFlagsChanged().
+     *
+     * \return Bitfield combination of flags, as defined in #ChannelGroupFlag.
+     */
+    uint groupFlags() const;
+
+    /**
+     * Returns the current members of the group.
+     *
+     * \return Set of handles representing the members.
+     */
+    QSet<uint> groupMembers() const;
+
+    /**
+     * Class opaquely storing information on a group membership change for a
+     * single member.
+     *
+     * Extended information is not always available; this will be reflected by
+     * the return value of isValid().
+     */
+    class GroupMemberChangeInfo
+    {
+    public:
+
+        /**
+         * \internal
+         */
+        GroupMemberChangeInfo()
+            : mActor(-1), mReason(0), mIsValid(false) {}
+
+        /**
+         * \internal
+         */
+        GroupMemberChangeInfo(uint actor, uint reason, const QString& message)
+            : mActor(actor), mReason(reason), mMessage(message), mIsValid(true) {}
+
+        /**
+         * Returns whether or not this object actually contains valid
+         * information received from the service. If the returned value is
+         * false, the values returned by the other methods for this object are
+         * undefined.
+         *
+         * \return Whether the information stored in this object is valid.
+         */
+        bool isValid() const { return mIsValid; }
+
+        /**
+         * Returns the contact requesting or causing the change.
+         *
+         * \return The handle of the contact.
+         */
+        uint actor() const { return mActor; }
+
+        /**
+         * Returns the reason for the change.
+         *
+         * \return The reason, as specified in #ChannelGroupChangeReason.
+         */
+        uint reason() const { return mReason; }
+
+        /**
+         * Returns a human-readable message from the contact represented by
+         * actor() pertaining to the change, or an empty string if there is no
+         * message.
+         *
+         * \return The message as a string.
+         */
+        const QString& message() const { return mMessage; }
+
+    private:
+        uint mActor;
+        uint mReason;
+        QString mMessage;
+        bool mIsValid;
+    };
+
+    /**
+     * Mapping from contact handles to local pending contact information.
+     */
+    typedef QMap<uint, GroupMemberChangeInfo> GroupMemberChangeInfoMap;
+
+    /**
+     * Returns the contacts currently waiting for local approval to join the
+     * group.
+     *
+     * The returned value is a mapping from contact handles to
+     * GroupMemberChangeInfo objects. The key specifies a contact, with the
+     * value potentially including extendend information on the original request
+     * leading to the contact appearing in the local pending members.
+     *
+     * A info object as a value in the mapping, for which
+     * GroupMemberChangeInfo::isValid() returns <code>false</code> indicates a
+     * member for which no extended information has been received from the
+     * service. This will only happen for old services, for which neither the
+     * LocalPending property nor the GetLocalPendingMembersWithInfo method is
+     * usable.
+     *
+     * \returns A mapping from handles to info for the members waiting for local
+     *          approval.
+     */
+    GroupMemberChangeInfoMap groupLocalPending() const;
+
+    /**
+     * Returns the contacts currently waiting for remote approval to join the
+     * group.
+     *
+     * \returns Set of handles representing the contacts.
+     */
+    QSet<uint> groupRemotePending() const;
+
+    /**
+     * Returns whether globally valid handles can be looked up using the
+     * channel-specific handle on this channel using this object.
+     *
+     * Handle owner lookup is only available if:
+     * <ul>
+     *  <li>The object has readiness #ReadinessFull
+     *  <li>The list returned by interfaces() contains
+     *        #TELEPATHY_INTERFACE_CHANNEL_INTERFACE_GROUP</li>
+     *  <li>The set of flags returned by groupFlags() contains
+     *        GroupFlagProperties and GroupFlagChannelSpecificHandles</li>
+     * </ul>
+     *
+     * If this function returns <code>false</code>, the return value of
+     * groupHandleOwners() is undefined and groupHandleOwnersChanged() will
+     * never be emitted.
+     *
+     * The value returned by this function will stay fixed for the entire time
+     * the object spends having readiness #ReadinessFull, so no change
+     * notification is provided.
+     *
+     * \return If handle owner lookup functionality is available.
+     */
+    bool groupAreHandleOwnersAvailable() const;
+
+    /**
+     * Returns a mapping of handles specific to this channel to globally valid
+     * handles.
+     *
+     * The mapping includes at least all of the channel-specific handles in this
+     * channel's members, local-pending and remote-pending sets as keys. Any
+     * handle not in the keys of this mapping is not channel-specific in this
+     * channel. Handles which are channel-specific, but for which the owner is
+     * unknown, appear in this mapping with 0 as owner.
+     *
+     * \return A mapping from group-specific handles to globally valid handles.
+     */
+    HandleOwnerMap groupHandleOwners() const;
+
+    /**
+     * Returns whether the value returned by groupSelfHandle() is guaranteed to
+     * stay synchronized with what groupInterface()->GetSelfHandle() would
+     * return. Older services not providing group properties don't necessarily
+     * emit the SelfHandleChanged signal either, so self handle changes can't be
+     * reliably tracked.
+     *
+     * \return Whether or not changes to the self handle are tracked.
+     */
+    bool groupIsSelfHandleTracked() const;
+
+    /**
+     * Returns a handle representing the user in the group if the user is a
+     * member of the group, otherwise either a handle representing the user or
+     * 0.
+     *
+     * \return A contact handle representing the user, if possible.
+     */
+    uint groupSelfHandle() const;
+
+    /**
+     * Returns information on the removal of the local user from the group. If
+     * the user hasn't been removed from the group, an object for which
+     * GroupMemberChangeInfo::isValid() returns <code>false</code> is returned.
+     *
+     * This method only after the channel has gone into readiness
+     * #ReadinessClosed. This is useful for getting the
+     * remove information after missing the corresponding groupMembersChanged()
+     * (or groupLocalPendingChanged()/groupRemotePendingChanged()) signal, as
+     * the local user being removed usually causes the remote %Channel to be
+     * closed, and consequently the Channel object going into that readiness
+     * state.
+     *
+     * The returned information is not guaranteed to be correct if
+     * groupIsSelfHandleTracked() returns false and a self handle change has
+     * occurred on the remote object.
+     *
+     * \return The remove info in a GroupMemberChangeInfo object.
+     */
+    GroupMemberChangeInfo groupSelfRemoveInfo() const;
+
+Q_SIGNALS:
+
+    /**
+     * Emitted when the value returned by groupFlags() changes.
+     *
+     * \param flags The value which would now be returned by groupFlags().
+     * \param added Flags added compared to the previous value.
+     * \param removed Flags removed compared to the previous value.
+     */
+    void groupFlagsChanged(uint flags, uint added, uint removed);
+
+    /**
+     * Emitted when the value returned by groupMembers() changes.
+     *
+     * \param members The value which would now be returned by groupMembers().
+     * \param added Handles of the contacts which were added to the value.
+     * \param removed Handles of the contacts which were removed from the value.
+     * \param actor Handle of the contact requesting or causing the change.
+     * \param reason Reason of the change, as specified in
+     *        #ChannelGroupChangeReason.
+     * \param message Message specified by the actor related to the change, such
+     *        as the part message in IRC.
+     */
+    void groupMembersChanged(const QSet<uint>& members, const Telepathy::UIntList& added, const Telepathy::UIntList& removed, uint actor, uint reason, const QString& message);
+
+    /**
+     * Emitted when the value returned by groupLocalPending() changes.
+     *
+     * The added and remove lists only specify the handles of the contacts added
+     * to or removed from the mapping, not the extended information pertaining
+     * to them. Local pending info never changes for a particular contact after
+     * the contact first appears in the mapping, so no change notification is
+     * necessary for the extended information itself.
+     *
+     * \param localPending The value which would now be returned by
+     *        groupLocalPending().
+     * \param added Handles of the contacts which were added to the value.
+     * \param removed Handles of the contacts which were removed from the value.
+     * \param actor Handle of the contact requesting or causing the change.
+     * \param reason Reason of the change, as specified in
+     *        #ChannelGroupChangeReason.
+     * \param message Message specified by the actor related to the change, such
+     *        as the part message in IRC.
+     */
+    void groupLocalPendingChanged(const GroupMemberChangeInfoMap& localPending, const Telepathy::UIntList& added, const Telepathy::UIntList& removed, uint actor, uint reason, const QString& message);
+
+    /**
+     * Emitted when the value returned by groupRemotePending() changes.
+     *
+     * \param remotePending The value which would now be returned by
+     *        groupRemotePending().
+     * \param added Handles of the contacts which were added to the value.
+     * \param removed Handles of the contacts which were removed from the value.
+     * \param actor Handle of the contact requesting or causing the change.
+     * \param reason Reason of the change, as specified in
+     *        #ChannelGroupChangeReason.
+     * \param message Message specified by the actor related to the change, such
+     *        as the part message in IRC.
+     */
+    void groupRemotePendingChanged(const QSet<uint>& remotePending, const Telepathy::UIntList& added, const Telepathy::UIntList& removed, uint actor, uint reason, const QString& message);
+
+    /**
+     * Emitted when the value returned by groupHandleOwners() changes.
+     *
+     * \param owners The value which would now be returned by
+     *               groupHandleOwners().
+     * \param added Handles which have been added to the mapping as keys, or
+     *              existing handle keys for which the mapped-to value has changed.
+     * \param removed Handles which have been removed from the mapping.
+     */
+    void groupHandleOwnersChanged(const HandleOwnerMap& owners, const Telepathy::UIntList& added, const Telepathy::UIntList& removed);
+
+    /**
+     * Emitted when the value returned by groupSelfHandle() changes.
+     *
+     * \param selfHandle The value which would now be returned by
+     *                   groupSelfHandle().
+     */
+    void groupSelfHandleChanged(uint selfHandle);
+
+    /**
+     * \name Optional interface proxy factory
+     *
+     * Factory functions fabricating proxies for optional %Channel interfaces and
+     * interfaces for specific channel types.
+     */
+    //@{
+
+public:
+
+    /**
+     * Specifies if the interface being supported by the remote object should be
+     * checked by optionalInterface(), typeInterface() and the convenience
+     * functions for them.
+     */
+    enum InterfaceSupportedChecking
+    {
+        /**
+         * Don't return an interface instance unless it can be guaranteed that
+         * the remote object actually implements the interface.
+         */
+        CheckInterfaceSupported,
+
+        /**
+         * Return an interface instance even if it can't be verified that the
+         * remote object supports the interface.
+         */
+        BypassInterfaceCheck
+    };
+
+    /**
+     * Returns a pointer to a valid instance of a given %Channel optional
+     * interface class, associated with the same remote object the Channel is
+     * associated with, and destroyed together with the Channel.
+     *
+     * If the list returned by interfaces() doesn't contain the name of the
+     * interface requested <code>0</code> is returned. This check can be
+     * bypassed by specifying #BypassInterfaceCheck for <code>check</code>, in
+     * which case a valid instance is always returned.
+     *
+     * If the object doesn't have readiness #ReadinessFull, the list returned by
+     * interfaces() isn't guaranteed to yet represent the full set of interfaces
+     * supported by the remote object. Hence the check might fail even if the
+     * remote object actually supports the requested interface; using
+     * #BypassInterfaceCheck is suggested when the channel is not fully ready.
+     *
+     * \see OptionalInterfaceFactory::interface
+     *
+     * \tparam Interface Class of the optional interface to get.
+     * \param check Should an instance be returned even if it can't be
+     *              determined that the remote object supports the
+     *              requested interface.
+     * \return Pointer to an instance of the interface class, or <code>0</code>.
+     */
+    template <class Interface>
+    inline Interface* optionalInterface(InterfaceSupportedChecking check = CheckInterfaceSupported) const
+    {
+        // Check for the remote object supporting the interface
+        QString name(Interface::staticInterfaceName());
+        if (check == CheckInterfaceSupported && !interfaces().contains(name))
+            return 0;
+
+        // If present or forced, delegate to OptionalInterfaceFactory
+        return OptionalInterfaceFactory::interface<Interface>(*baseInterface());
+    }
+
+    /**
+     * Convenience function for getting a CallState interface proxy.
+     *
+     * \param check Passed to optionalInterface()
+     * \return <code>optionalInterface<ChannelInterfaceCallStateInterface>(check)</code>
+     */
+    inline ChannelInterfaceCallStateInterface* callStateInterface(InterfaceSupportedChecking check = CheckInterfaceSupported) const
+    {
+        return optionalInterface<ChannelInterfaceCallStateInterface>(check);
+    }
+
+    /**
+     * Convenience function for getting a ChatState interface proxy.
+     *
+     * \param check Passed to optionalInterface()
+     * \return <code>optionalInterface<ChannelInterfaceChatStateInterface>(check)</code>
+     */
+    inline ChannelInterfaceChatStateInterface* chatStateInterface(InterfaceSupportedChecking check = CheckInterfaceSupported) const
+    {
+        return optionalInterface<ChannelInterfaceChatStateInterface>(check);
+    }
+
+    /**
+     * Convenience function for getting a DTMF interface proxy.
+     *
+     * \param check Passed to optionalInterface()
+     * \return <code>optionalInterface<ChannelInterfaceDTMFInterface>(check)</code>
+     */
+    inline ChannelInterfaceDTMFInterface* DTMFInterface(InterfaceSupportedChecking check = CheckInterfaceSupported) const
+    {
+        return optionalInterface<ChannelInterfaceDTMFInterface>(check);
+    }
+
+    /**
+     * Convenience function for getting a Group interface proxy.
+     *
+     * \param check Passed to optionalInterface()
+     * \return <code>optionalInterface<ChannelInterfaceGroupInterface>(check)</code>
+     */
+    inline ChannelInterfaceGroupInterface* groupInterface(InterfaceSupportedChecking check = CheckInterfaceSupported) const
+    {
+        return optionalInterface<ChannelInterfaceGroupInterface>(check);
+    }
+
+    /**
+     * Convenience function for getting a Hold interface proxy.
+     *
+     * \param check Passed to optionalInterface()
+     * \return <code>optionalInterface<ChannelInterfaceHoldInterface>(check)</code>
+     */
+    inline ChannelInterfaceHoldInterface* holdInterface(InterfaceSupportedChecking check = CheckInterfaceSupported) const
+    {
+        return optionalInterface<ChannelInterfaceHoldInterface>(check);
+    }
+
+    /**
+     * Convenience function for getting a MediaSignalling interface proxy.
+     *
+     * \param check Passed to optionalInterface()
+     * \return <code>optionalInterface<ChannelInterfaceMediaSignallingInterface>(check)</code>
+     */
+    inline ChannelInterfaceMediaSignallingInterface* mediaSignallingInterface(InterfaceSupportedChecking check = CheckInterfaceSupported) const
+    {
+        return optionalInterface<ChannelInterfaceMediaSignallingInterface>(check);
+    }
+
+    /**
+     * Convenience function for getting a Password interface proxy.
+     *
+     * \param check Passed to optionalInterface()
+     * \return <code>optionalInterface<ChannelInterfacePasswordInterface>(check)</code>
+     */
+    inline ChannelInterfacePasswordInterface* passwordInterface(InterfaceSupportedChecking check = CheckInterfaceSupported) const
+    {
+        return optionalInterface<ChannelInterfacePasswordInterface>(check);
+    }
+
+    /**
+     * Convenience function for getting a Properties interface proxy. The
+     * Properties interface is not necessarily reported by the services, so a
+     * <code>check</code> parameter is not provided, and the interface is always
+     * assumed to be present.
+     *
+     * \return
+     * <code>optionalInterface<DBus::PropertiesInterface>(BypassInterfaceCheck)</code>
+     */
+    inline DBus::PropertiesInterface* propertiesInterface() const
+    {
+        return optionalInterface<DBus::PropertiesInterface>(BypassInterfaceCheck);
+    }
+
+    /**
+     * Returns a pointer to a valid instance of a given %Channel type interface
+     * class, associated with the same remote object the Channel is
+     * associated with, and destroyed together with the Channel.
+     *
+     * If the interface name returned by channelType() isn't equivalent to the
+     * name of the requested interface, or the Channel doesn't have readiness
+     * #ReadinessFull, <code>0</code> is returned. This check can be bypassed by
+     * specifying #BypassInterfaceCheck for <code>check</code>, in which case a
+     * valid instance is always returned.
+     *
+     * Convenience functions are provided for well-known channel types. However,
+     * there is no convenience getter for TypeContactList because the proxy for
+     * that interface doesn't actually have any functionality.
+     *
+     * \see OptionalInterfaceFactory::interface
+     *
+     * \tparam Interface Class of the optional interface to get.
+     * \param check Should an instance be returned even if it can't be
+     *              determined that the remote object is of the requested
+     *              channel type.
+     * \return Pointer to an instance of the interface class, or <code>0</code>.
+     */
+    template <class Interface>
+    inline Interface* typeInterface(InterfaceSupportedChecking check = CheckInterfaceSupported) const
+    {
+        // Check for the remote object having the correct channel type
+        QString name(Interface::staticInterfaceName());
+        if (check == CheckInterfaceSupported && channelType() != name)
+            return 0;
+
+        // If correct type or check bypassed, delegate to OIF
+        return OptionalInterfaceFactory::interface<Interface>(*baseInterface());
+    }
+
+    /**
+     * Convenience function for getting a TypeRoomList interface proxy.
+     *
+     * \param check Passed to typeInterface()
+     * \return <code>typeInterface<ChannelTypeRoomListInterface>(check)</code>
+     */
+    inline ChannelTypeRoomListInterface* roomListInterface(InterfaceSupportedChecking check = CheckInterfaceSupported) const
+    {
+        return typeInterface<ChannelTypeRoomListInterface>(check);
+    }
+
+    /**
+     * Convenience function for getting a TypeStreamedMedia interface proxy.
+     *
+     * \param check Passed to typeInterface()
+     * \return <code>typeInterface<ChannelTypeStreamedMediaInterface>(check)</code>
+     */
+    inline ChannelTypeStreamedMediaInterface* streamedMediaInterface(InterfaceSupportedChecking check = CheckInterfaceSupported) const
+    {
+        return typeInterface<ChannelTypeStreamedMediaInterface>(check);
+    }
+
+    /**
+     * Convenience function for getting a TypeText interface proxy.
+     *
+     * \param check Passed to typeInterface()
+     * \return <code>typeInterface<ChannelTypeTextInterface>(check)</code>
+     */
+    inline ChannelTypeTextInterface* textInterface(InterfaceSupportedChecking check = CheckInterfaceSupported) const
+    {
+        return typeInterface<ChannelTypeTextInterface>(check);
+    }
+
+    /**
+     * Convenience function for getting a TypeTubes interface proxy.
+     *
+     * \param check Passed to typeInterface()
+     * \return <code>typeInterface<ChannelTypeTubesInterface>(check)</code>
+     */
+    inline ChannelTypeTubesInterface* tubesInterface(InterfaceSupportedChecking check = CheckInterfaceSupported) const
+    {
+        return typeInterface<ChannelTypeTubesInterface>(check);
+    }
+
+protected:
+    /**
+     * Get the ChannelInterface for this Channel class. This method is
+     * protected since the convenience methods provided by this class should
+     * always be used instead of the interface by users of the class.
+     *
+     * \return A pointer to the existing ChannelInterface for this Channel
+     */
+    ChannelInterface* baseInterface() const;
+
+    //@}
+
+private Q_SLOTS:
+    void gotMainProperties(QDBusPendingCallWatcher* watcher);
+    void gotChannelType(QDBusPendingCallWatcher* watcher);
+    void gotHandle(QDBusPendingCallWatcher* watcher);
+    void gotInterfaces(QDBusPendingCallWatcher* watcher);
+    void onClosed();
+
+    void onConnectionReadinessChanged(uint readiness);
+    void onConnectionDestroyed();
+
+    void gotGroupProperties(QDBusPendingCallWatcher* watcher);
+    void gotGroupFlags(QDBusPendingCallWatcher* watcher);
+    void gotAllMembers(QDBusPendingCallWatcher* watcher);
+    void gotLocalPending(QDBusPendingCallWatcher* watcher);
+    void gotSelfHandle(QDBusPendingCallWatcher* watcher);
+    void onGroupFlagsChanged(uint, uint);
+    void onMembersChanged(const QString&, const Telepathy::UIntList&, const Telepathy::UIntList&, const Telepathy::UIntList&, const Telepathy::UIntList&, uint, uint);
+    void onHandleOwnersChanged(const Telepathy::HandleOwnerMap&, const Telepathy::UIntList&);
+    void onSelfHandleChanged(uint);
+
+private:
+    struct Private;
+    friend struct Private;
+    Private *mPriv;
+};
+
+}
+}
+
+Q_DECLARE_METATYPE(Telepathy::Client::Channel::GroupMemberChangeInfo);
+Q_DECLARE_METATYPE(Telepathy::Client::Channel::GroupMemberChangeInfoMap);
+
+#endif
diff --git a/TelepathyQt4/Client/connection-manager.cpp b/TelepathyQt4/Client/connection-manager.cpp
new file mode 100644
index 0000000..415ab9d
--- /dev/null
+++ b/TelepathyQt4/Client/connection-manager.cpp
@@ -0,0 +1,459 @@
+/*
+ * This file is part of TelepathyQt4
+ *
+ * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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 St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include "connection-manager.h"
+#include "connection-manager.moc.hpp"
+
+#include <TelepathyQt4/_gen/cli-connection-manager-body.hpp>
+#include <TelepathyQt4/_gen/cli-connection-manager.moc.hpp>
+
+#include <TelepathyQt4/Client/DBus>
+#include <TelepathyQt4/ManagerFile>
+#include <TelepathyQt4/Types>
+#include <TelepathyQt4/debug-internal.hpp>
+
+#include <QQueue>
+#include <QStringList>
+#include <QTimer>
+
+namespace Telepathy
+{
+namespace Client
+{
+
+ProtocolParameter::ProtocolParameter(const QString &name,
+                                     const QDBusSignature &dbusSignature,
+                                     QVariant defaultValue,
+                                     Telepathy::ConnMgrParamFlag flags)
+    : mName(name),
+      mDBusSignature(dbusSignature),
+      mType(ManagerFile::variantFromDBusSignature("", dbusSignature.signature())),
+      mDefaultValue(defaultValue),
+      mFlags(flags)
+{
+}
+
+
+ProtocolParameter::~ProtocolParameter()
+{
+}
+
+
+bool ProtocolParameter::isRequired() const
+{
+    return mFlags & ConnMgrParamFlagRequired;
+}
+
+
+bool ProtocolParameter::isSecret() const
+{
+    return mFlags & ConnMgrParamFlagSecret;
+}
+
+
+bool ProtocolParameter::requiredForRegistration() const
+{
+    return mFlags & ConnMgrParamFlagRegister;
+}
+
+
+bool ProtocolParameter::operator==(const ProtocolParameter &other) const
+{
+    return (mName == other.name());
+}
+
+
+bool ProtocolParameter::operator==(const QString &name) const
+{
+    return (mName == name);
+}
+
+
+struct ProtocolInfo::Private
+{
+    ProtocolParameterList params;
+};
+
+
+ProtocolInfo::ProtocolInfo(const QString &cmName, const QString &name)
+    : mPriv(new Private()),
+      mCmName(cmName),
+      mName(name)
+{
+}
+
+
+ProtocolInfo::~ProtocolInfo()
+{
+    Q_FOREACH (ProtocolParameter *param, mPriv->params) {
+        delete param;
+    }
+}
+
+
+const ProtocolParameterList &ProtocolInfo::parameters() const
+{
+    return mPriv->params;
+}
+
+
+bool ProtocolInfo::hasParameter(const QString &name) const
+{
+    Q_FOREACH (ProtocolParameter *param, mPriv->params) {
+        if (param->name() == name) {
+            return true;
+        }
+    }
+    return false;
+}
+
+
+bool ProtocolInfo::canRegister() const
+{
+    return hasParameter(QLatin1String("register"));
+}
+
+
+void ProtocolInfo::addParameter(const ParamSpec &spec)
+{
+    QVariant defaultValue;
+    if (spec.flags & ConnMgrParamFlagHasDefault)
+        defaultValue = spec.defaultValue.variant();
+
+    uint flags = spec.flags;
+    if (spec.name.endsWith("password"))
+        flags |= Telepathy::ConnMgrParamFlagSecret;
+
+    ProtocolParameter *param = new ProtocolParameter(spec.name,
+            QDBusSignature(spec.signature),
+            defaultValue,
+            (Telepathy::ConnMgrParamFlag) flags);
+
+    mPriv->params.append(param);
+}
+
+
+struct ConnectionManager::Private
+{
+    ConnectionManager *parent;
+    ConnectionManagerInterface* baseInterface;
+    bool ready;
+    QQueue<void (Private::*)()> introspectQueue;
+    QQueue<QString> getParametersQueue;
+    QQueue<QString> protocolQueue;
+    QStringList interfaces;
+    ProtocolInfoList protocols;;
+
+    Private(ConnectionManager *parent);
+    ~Private();
+
+    static QString makeBusName(const QString& name);
+    static QString makeObjectPath(const QString& name);
+
+    ProtocolInfo *protocol(const QString &protocolName);
+
+    bool checkConfigFile();
+    void callReadConfig();
+    void callGetAll();
+    void callGetParameters();
+    void callListProtocols();
+};
+
+
+ConnectionManager::Private::Private(ConnectionManager *parent)
+    : parent(parent),
+      baseInterface(new ConnectionManagerInterface(parent->dbusConnection(),
+                    parent->busName(), parent->objectPath(), parent)),
+      ready(false)
+{
+    debug() << "Creating new ConnectionManager:" << parent->busName();
+
+    introspectQueue.enqueue(&Private::callReadConfig);
+    QTimer::singleShot(0, parent, SLOT(continueIntrospection()));
+}
+
+
+ConnectionManager::Private::~Private()
+{
+    Q_FOREACH (ProtocolInfo* info, protocols) {
+        delete info;
+    }
+}
+
+
+QString ConnectionManager::Private::makeBusName(const QString& name)
+{
+    return QString::fromAscii(
+            TELEPATHY_CONNECTION_MANAGER_BUS_NAME_BASE).append(name);
+}
+
+
+QString ConnectionManager::Private::makeObjectPath(const QString& name)
+{
+    return QString::fromAscii(
+            TELEPATHY_CONNECTION_MANAGER_OBJECT_PATH_BASE).append(name);
+}
+
+
+ProtocolInfo *ConnectionManager::Private::protocol(const QString &protocolName)
+{
+    Q_FOREACH (ProtocolInfo *info, protocols) {
+        if (info->name() == protocolName) {
+            return info;
+        }
+    }
+    return NULL;
+}
+
+
+bool ConnectionManager::Private::checkConfigFile()
+{
+    ManagerFile f(parent->name());
+    if (!f.isValid()) {
+        return false;
+    }
+
+    Q_FOREACH (QString protocol, f.protocols()) {
+        ProtocolInfo *info = new ProtocolInfo(parent->name(),
+                                              protocol);
+        protocols.append(info);
+
+        Q_FOREACH (ParamSpec spec, f.parameters(protocol)) {
+            info->addParameter(spec);
+        }
+    }
+
+#if 0
+    Q_FOREACH (ProtocolInfo *info, protocols) {
+        qDebug() << "protocol name   :" << info->name();
+        qDebug() << "protocol cn name:" << info->cmName();
+        Q_FOREACH (ProtocolParameter *param, info->parameters()) {
+            qDebug() << "\tparam name:       " << param->name();
+            qDebug() << "\tparam is required:" << param->isRequired();
+            qDebug() << "\tparam is secret:  " << param->isSecret();
+            qDebug() << "\tparam value:      " << param->defaultValue();
+        }
+    }
+#endif
+
+    return true;
+}
+
+
+void ConnectionManager::Private::callReadConfig()
+{
+    if (!checkConfigFile()) {
+        introspectQueue.enqueue(&Private::callGetAll);
+        introspectQueue.enqueue(&Private::callListProtocols);
+    }
+
+    parent->continueIntrospection();
+}
+
+
+void ConnectionManager::Private::callGetAll()
+{
+    debug() << "Calling Properties::GetAll(ConnectionManager)";
+    QDBusPendingCallWatcher* watcher = new QDBusPendingCallWatcher(
+            parent->propertiesInterface()->GetAll(
+                TELEPATHY_INTERFACE_CONNECTION_MANAGER), parent);
+    parent->connect(watcher,
+            SIGNAL(finished(QDBusPendingCallWatcher*)),
+            SLOT(onGetAllConnectionManagerReturn(QDBusPendingCallWatcher*)));
+}
+
+
+void ConnectionManager::Private::callGetParameters()
+{
+    QString protocol = getParametersQueue.dequeue();
+    protocolQueue.enqueue(protocol);
+    debug() << "Calling ConnectionManager::GetParameters(" <<
+        protocol << ")";
+    QDBusPendingCallWatcher* watcher = new QDBusPendingCallWatcher(
+            baseInterface->GetParameters(protocol), parent);
+    parent->connect(watcher,
+            SIGNAL(finished(QDBusPendingCallWatcher*)),
+            SLOT(onGetParametersReturn(QDBusPendingCallWatcher*)));
+}
+
+
+void ConnectionManager::Private::callListProtocols()
+{
+    debug() << "Calling ConnectionManager::ListProtocols";
+    QDBusPendingCallWatcher* watcher = new QDBusPendingCallWatcher(
+            baseInterface->ListProtocols(), parent);
+    parent->connect(watcher,
+            SIGNAL(finished(QDBusPendingCallWatcher*)),
+            SLOT(onListProtocolsReturn(QDBusPendingCallWatcher*)));
+}
+
+
+ConnectionManager::ConnectionManager(const QString& name, QObject* parent)
+    : StatelessDBusProxy(QDBusConnection::sessionBus(),
+            Private::makeBusName(name), Private::makeObjectPath(name),
+            parent),
+      mPriv(new Private(this)),
+      mName(name)
+{
+}
+
+
+ConnectionManager::ConnectionManager(const QDBusConnection& bus,
+        const QString& name, QObject* parent)
+    : StatelessDBusProxy(bus, Private::makeBusName(name),
+            Private::makeObjectPath(name), parent),
+      mPriv(new Private(this)),
+      mName(name)
+{
+}
+
+
+ConnectionManager::~ConnectionManager()
+{
+    delete mPriv;
+}
+
+
+QStringList ConnectionManager::interfaces() const
+{
+    return mPriv->interfaces;
+}
+
+
+QStringList ConnectionManager::supportedProtocols() const
+{
+    QStringList protocols;
+    Q_FOREACH (const ProtocolInfo *info, mPriv->protocols) {
+        protocols.append(info->name());
+    }
+    return protocols;
+}
+
+
+const ProtocolInfoList &ConnectionManager::protocols() const
+{
+    return mPriv->protocols;
+}
+
+
+bool ConnectionManager::isReady() const
+{
+    return mPriv->ready;
+}
+
+
+ConnectionManagerInterface* ConnectionManager::baseInterface() const
+{
+    return mPriv->baseInterface;
+}
+
+
+void ConnectionManager::onGetAllConnectionManagerReturn(
+        QDBusPendingCallWatcher* watcher)
+{
+    QDBusPendingReply<QVariantMap> reply = *watcher;
+    QVariantMap props;
+
+    if (!reply.isError()) {
+        debug() << "Got reply to Properties.GetAll(ConnectionManager)";
+        props = reply.value();
+    } else {
+        warning().nospace() <<
+            "Properties.GetAll(ConnectionManager) failed: " <<
+            reply.error().name() << ": " << reply.error().message();
+    }
+
+    // If Interfaces is not supported, the spec says to assume it's
+    // empty, so keep the empty list mPriv was initialized with
+    if (props.contains("Interfaces")) {
+        mPriv->interfaces = qdbus_cast<QStringList>(props["Interfaces"]);
+    }
+    continueIntrospection();
+}
+
+
+void ConnectionManager::onListProtocolsReturn(
+        QDBusPendingCallWatcher* watcher)
+{
+    QDBusPendingReply<QStringList> reply = *watcher;
+    QStringList protocols;
+
+    if (!reply.isError()) {
+        debug() << "Got reply to ConnectionManager.ListProtocols";
+        protocols = reply.value();
+    } else {
+        warning().nospace() <<
+            "ConnectionManager.ListProtocols failed: " <<
+            reply.error().name() << ": " << reply.error().message();
+    }
+
+    Q_FOREACH (const QString &protocolName, protocols) {
+        mPriv->protocols.append(new ProtocolInfo(mName,
+                                                 protocolName));
+
+        mPriv->getParametersQueue.enqueue(protocolName);
+        mPriv->introspectQueue.enqueue(&Private::callGetParameters);
+    }
+    continueIntrospection();
+}
+
+
+void ConnectionManager::onGetParametersReturn(
+        QDBusPendingCallWatcher* watcher)
+{
+    QDBusPendingReply<ParamSpecList> reply = *watcher;
+    ParamSpecList parameters;
+    QString protocolName = mPriv->protocolQueue.dequeue();
+    ProtocolInfo *info = mPriv->protocol(protocolName);
+
+    if (!reply.isError()) {
+        debug() << "Got reply to ConnectionManager.GetParameters";
+        parameters = reply.value();
+    } else {
+        warning().nospace() <<
+            "ConnectionManager.GetParameters failed: " <<
+            reply.error().name() << ": " << reply.error().message();
+    }
+
+    Q_FOREACH (const ParamSpec& spec, parameters) {
+        debug() << "Parameter" << spec.name << "has flags" << spec.flags
+            << "and signature" << spec.signature;
+
+        info->addParameter(spec);
+    }
+    continueIntrospection();
+}
+
+void ConnectionManager::continueIntrospection()
+{
+    if (!mPriv->ready) {
+        if (mPriv->introspectQueue.isEmpty()) {
+            debug() << "ConnectionManager is ready";
+            mPriv->ready = true;
+            Q_EMIT ready(this);
+        } else {
+            (mPriv->*(mPriv->introspectQueue.dequeue()))();
+        }
+    }
+}
+
+} // Telepathy::Client
+} // Telepathy
diff --git a/TelepathyQt4/Client/connection-manager.h b/TelepathyQt4/Client/connection-manager.h
new file mode 100644
index 0000000..fd81335
--- /dev/null
+++ b/TelepathyQt4/Client/connection-manager.h
@@ -0,0 +1,234 @@
+/*
+ * This file is part of TelepathyQt4
+ *
+ * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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 St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef _TelepathyQt4_cli_connection_manager_h_HEADER_GUARD_
+#define _TelepathyQt4_cli_connection_manager_h_HEADER_GUARD_
+
+/**
+ * \addtogroup clientsideproxies Client-side proxies
+ *
+ * Proxy objects representing remote service objects accessed via D-Bus.
+ *
+ * In addition to providing direct access to methods, signals and properties
+ * exported by the remote objects, some of these proxies offer features like
+ * automatic inspection of remote object capabilities, property tracking,
+ * backwards compatibility helpers for older services and other utilities.
+ */
+
+/**
+ * \defgroup clientcm Connection manager proxies
+ * \ingroup clientsideproxies
+ *
+ * Proxy objects representing remote Telepathy ConnectionManager objects.
+ */
+
+#include <TelepathyQt4/_gen/cli-connection-manager.h>
+
+#include <TelepathyQt4/Client/DBus>
+#include <TelepathyQt4/Client/DBusProxy>
+#include <TelepathyQt4/Client/OptionalInterfaceFactory>
+#include <TelepathyQt4/Constants>
+
+namespace Telepathy
+{
+namespace Client
+{
+
+class ProtocolParameter;
+class ProtocolInfo;
+
+typedef QList<ProtocolParameter*> ProtocolParameterList;
+typedef QList<ProtocolInfo*> ProtocolInfoList;
+
+class ProtocolParameter
+{
+public:
+    ProtocolParameter(const QString &name,
+                      const QDBusSignature &dbusSignature,
+                      QVariant defaultValue,
+                      Telepathy::ConnMgrParamFlag flags);
+    ~ProtocolParameter();
+
+    QString name() const { return mName; }
+    QDBusSignature dbusSignature() const { return mDBusSignature; }
+    QVariant type() const { return mType; }
+    QVariant defaultValue() const { return mDefaultValue; }
+
+    bool isRequired() const;
+    bool isSecret() const;
+    bool requiredForRegistration() const;
+
+    bool operator==(const ProtocolParameter &other) const;
+    bool operator==(const QString &name) const;
+
+private:
+    Q_DISABLE_COPY(ProtocolParameter);
+
+    QString mName;
+    QDBusSignature mDBusSignature;
+    QVariant mType;
+    QVariant mDefaultValue;
+    Telepathy::ConnMgrParamFlag mFlags;
+};
+
+
+class ProtocolInfo
+{
+public:
+    ~ProtocolInfo();
+
+    /**
+     * Get the short name of the connection manager (e.g. "gabble").
+     *
+     * \return The name of the connection manager
+     */
+    QString cmName() const { return mCmName; }
+
+    /**
+     * Get the untranslated name of the protocol as described in the Telepathy
+     * D-Bus API Specification (e.g. "jabber").
+     */
+    QString name() const { return mName; }
+
+    /**
+     * Return all supported parameters. The parameters' names
+     * may either be the well-known strings specified by the Telepathy D-Bus
+     * API Specification (e.g. "account" and "password"), or
+     * implementation-specific strings.
+     *
+     * \return A list of parameters
+     */
+    const ProtocolParameterList &parameters() const;
+
+    /**
+     * Return whether a given parameter can be passed to the connection
+     * manager when creating a connection to this protocol.
+     *
+     * \param name The name of a parameter
+     * \return true if the given parameter exists
+     */
+    bool hasParameter(const QString &name) const;
+
+    /**
+     * Return whether it might be possible to register new accounts on this
+     * protocol via Telepathy, by setting the special parameter named
+     * <code>register</code> to <code>true</code>.
+     *
+     * \return The same thing as hasParameter("register")
+     */
+    bool canRegister() const;
+
+private:
+    Q_DISABLE_COPY(ProtocolInfo);
+
+    ProtocolInfo(const QString &cmName, const QString &name);
+
+    void addParameter(const ParamSpec &spec);
+
+    struct Private;
+    friend struct Private;
+    friend class ConnectionManager;
+    Private *mPriv;
+    QString mCmName;
+    QString mName;
+};
+
+
+/**
+ * \class ConnectionManager
+ * \ingroup clientcm
+ * \headerfile TelepathyQt4/Client/connection-manager.h <TelepathyQt4/Client/ConnectionManager>
+ *
+ * Object representing a Telepathy connection manager. Connection managers
+ * allow connections to be made on one or more protocols.
+ *
+ * Most client applications should use this functionality via the
+ * %AccountManager, to allow connections to be shared between client
+ * applications.
+ */
+class ConnectionManager : public StatelessDBusProxy,
+        private OptionalInterfaceFactory
+{
+    Q_OBJECT
+
+public:
+    ConnectionManager(const QString& name, QObject* parent = 0);
+    ConnectionManager(const QDBusConnection& bus,
+            const QString& name, QObject* parent = 0);
+
+    virtual ~ConnectionManager();
+
+    QString name() const { return mName; }
+
+    QStringList interfaces() const;
+
+    QStringList supportedProtocols() const;
+
+    const ProtocolInfoList &protocols() const;
+
+    /**
+     * Convenience function for getting a Properties interface proxy. The
+     * Properties interface is not necessarily reported by the services, so a
+     * <code>check</code> parameter is not provided, and the interface is
+     * always assumed to be present.
+     */
+    inline DBus::PropertiesInterface* propertiesInterface() const
+    {
+        return OptionalInterfaceFactory::interface<DBus::PropertiesInterface>(
+                *baseInterface());
+    }
+
+    bool isReady() const;
+
+Q_SIGNALS:
+    void ready(ConnectionManager*);
+
+protected:
+    /**
+     * Get the ConnectionManagerInterface for this ConnectionManager. This
+     * method is protected since the convenience methods provided by this
+     * class should generally be used instead of calling D-Bus methods
+     * directly.
+     *
+     * \return A pointer to the existing ConnectionManagerInterface for this
+     *         ConnectionManager
+     */
+    ConnectionManagerInterface* baseInterface() const;
+
+private Q_SLOTS:
+    void onGetParametersReturn(QDBusPendingCallWatcher*);
+    void onListProtocolsReturn(QDBusPendingCallWatcher*);
+    void onGetAllConnectionManagerReturn(QDBusPendingCallWatcher*);
+    void continueIntrospection();
+
+private:
+    Q_DISABLE_COPY(ConnectionManager);
+
+    struct Private;
+    friend struct Private;
+    Private *mPriv;
+    QString mName;
+};
+
+}
+}
+
+#endif
diff --git a/TelepathyQt4/Client/connection.cpp b/TelepathyQt4/Client/connection.cpp
new file mode 100644
index 0000000..4e8ac84
--- /dev/null
+++ b/TelepathyQt4/Client/connection.cpp
@@ -0,0 +1,502 @@
+/*
+ * This file is part of TelepathyQt4
+ *
+ * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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 St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include "connection.h"
+#include "connection.moc.hpp"
+
+#include <TelepathyQt4/_gen/cli-connection-body.hpp>
+#include <TelepathyQt4/_gen/cli-connection.moc.hpp>
+
+#include <TelepathyQt4/Client/PendingChannel>
+#include <TelepathyQt4/Client/PendingVoidMethodCall>
+#include <TelepathyQt4/debug-internal.hpp>
+
+#include <QMap>
+#include <QQueue>
+#include <QString>
+#include <QtGlobal>
+
+namespace Telepathy
+{
+namespace Client
+{
+
+struct Connection::Private
+{
+    // Public object
+    Connection& parent;
+
+    // Instance of generated interface class
+    ConnectionInterface* baseInterface;
+
+    // Optional interface proxies
+    ConnectionInterfaceAliasingInterface* aliasing;
+    ConnectionInterfacePresenceInterface* presence;
+    DBus::PropertiesInterface* properties;
+
+    // Introspection
+    bool initialIntrospection;
+    Readiness readiness;
+    QStringList interfaces;
+    QQueue<void (Private::*)()> introspectQueue;
+
+    // Introspected properties
+    uint status;
+    uint statusReason;
+    uint aliasFlags;
+    StatusSpecMap presenceStatuses;
+    SimpleStatusSpecMap simplePresenceStatuses;
+
+    Private(Connection &parent)
+        : parent(parent)
+    {
+        aliasing = 0;
+        presence = 0;
+        properties = 0;
+        baseInterface = 0;
+
+        initialIntrospection = false;
+        readiness = ReadinessJustCreated;
+        status = ConnectionStatusDisconnected;
+        statusReason = ConnectionStatusReasonNoneSpecified;
+        aliasFlags = 0;
+    }
+
+    void startIntrospection()
+    {
+        Q_ASSERT(baseInterface == 0);
+        baseInterface = new ConnectionInterface(parent.dbusConnection(),
+            parent.busName(), parent.objectPath(), &parent);
+
+        debug() << "Connecting to StatusChanged()";
+
+        parent.connect(baseInterface,
+                       SIGNAL(StatusChanged(uint, uint)),
+                       SLOT(onStatusChanged(uint, uint)));
+
+        debug() << "Calling GetStatus()";
+
+        QDBusPendingCallWatcher* watcher =
+            new QDBusPendingCallWatcher(baseInterface->GetStatus(), &parent);
+        parent.connect(watcher,
+                       SIGNAL(finished(QDBusPendingCallWatcher*)),
+                       SLOT(gotStatus(QDBusPendingCallWatcher*)));
+    }
+
+    void introspectAliasing()
+    {
+        // The Aliasing interface is not usable before the connection is established
+        if (initialIntrospection) {
+            continueIntrospection();
+            return;
+        }
+
+        if (!aliasing) {
+            aliasing = parent.aliasingInterface();
+            Q_ASSERT(aliasing != 0);
+        }
+
+        debug() << "Calling GetAliasFlags()";
+        QDBusPendingCallWatcher* watcher =
+            new QDBusPendingCallWatcher(aliasing->GetAliasFlags(), &parent);
+        parent.connect(watcher,
+                       SIGNAL(finished(QDBusPendingCallWatcher*)),
+                       SLOT(gotAliasFlags(QDBusPendingCallWatcher*)));
+    }
+
+    void introspectMain()
+    {
+        // Introspecting the main interface is currently just calling
+        // GetInterfaces(), but it might include other stuff in the future if we
+        // gain GetAll-able properties on the connection
+        debug() << "Calling GetInterfaces()";
+        QDBusPendingCallWatcher* watcher =
+            new QDBusPendingCallWatcher(baseInterface->GetInterfaces(), &parent);
+        parent.connect(watcher,
+                       SIGNAL(finished(QDBusPendingCallWatcher*)),
+                       SLOT(gotInterfaces(QDBusPendingCallWatcher*)));
+    }
+
+    void introspectPresence()
+    {
+        // The Presence interface is not usable before the connection is established
+        if (initialIntrospection) {
+            continueIntrospection();
+            return;
+        }
+
+        if (!presence) {
+            presence = parent.presenceInterface();
+            Q_ASSERT(presence != 0);
+        }
+
+        debug() << "Calling GetStatuses() (legacy)";
+        QDBusPendingCallWatcher* watcher =
+            new QDBusPendingCallWatcher(presence->GetStatuses(), &parent);
+        parent.connect(watcher,
+                       SIGNAL(finished(QDBusPendingCallWatcher*)),
+                       SLOT(gotStatuses(QDBusPendingCallWatcher*)));
+    }
+
+    void introspectSimplePresence()
+    {
+        if (!properties) {
+            properties = parent.propertiesInterface();
+            Q_ASSERT(properties != 0);
+        }
+
+        debug() << "Getting available SimplePresence statuses";
+        QDBusPendingCall call =
+            properties->Get(TELEPATHY_INTERFACE_CONNECTION_INTERFACE_SIMPLE_PRESENCE,
+                           "Statuses");
+        QDBusPendingCallWatcher* watcher =
+            new QDBusPendingCallWatcher(call, &parent);
+        parent.connect(watcher,
+                       SIGNAL(finished(QDBusPendingCallWatcher*)),
+                       SLOT(gotSimpleStatuses(QDBusPendingCallWatcher*)));
+    }
+
+    void continueIntrospection()
+    {
+        if (introspectQueue.isEmpty()) {
+            if (initialIntrospection) {
+                initialIntrospection = false;
+                if (readiness < ReadinessNotYetConnected)
+                    changeReadiness(ReadinessNotYetConnected);
+            } else {
+                if (readiness != ReadinessDead)
+                    changeReadiness(ReadinessFull);
+            }
+        } else {
+            (this->*introspectQueue.dequeue())();
+        }
+    }
+
+    void changeReadiness(Readiness newReadiness)
+    {
+        Q_ASSERT(newReadiness != readiness);
+
+        switch (readiness) {
+            case ReadinessJustCreated:
+                break;
+            case ReadinessNotYetConnected:
+                Q_ASSERT(newReadiness == ReadinessConnecting
+                        || newReadiness == ReadinessDead);
+                break;
+            case ReadinessConnecting:
+                Q_ASSERT(newReadiness == ReadinessFull
+                        || newReadiness == ReadinessDead);
+                break;
+            case ReadinessFull:
+                Q_ASSERT(newReadiness == ReadinessDead);
+                break;
+            case ReadinessDead:
+            default:
+                Q_ASSERT(false);
+        }
+
+        debug() << "Readiness changed from" << readiness << "to" << newReadiness;
+        readiness = newReadiness;
+        emit parent.readinessChanged(newReadiness);
+    }
+};
+
+Connection::Connection(const QString& serviceName,
+                       const QString& objectPath,
+                       QObject* parent)
+    : StatefulDBusProxy(QDBusConnection::sessionBus(), serviceName,
+          objectPath, parent),
+      mPriv(new Private(*this))
+{
+    mPriv->startIntrospection();
+}
+
+Connection::Connection(const QDBusConnection& connection,
+                       const QString& serviceName,
+                       const QString& objectPath,
+                       QObject* parent)
+    : StatefulDBusProxy(connection, serviceName, objectPath, parent),
+      mPriv(new Private(*this))
+{
+    mPriv->startIntrospection();
+}
+
+Connection::~Connection()
+{
+    delete mPriv;
+}
+
+Connection::Readiness Connection::readiness() const
+{
+    return mPriv->readiness;
+}
+
+uint Connection::status() const
+{
+    if (mPriv->readiness == ReadinessJustCreated)
+        warning() << "Connection::status() used with readiness ReadinessJustCreated";
+
+    return mPriv->status;
+}
+
+uint Connection::statusReason() const
+{
+    if (mPriv->readiness == ReadinessJustCreated)
+        warning() << "Connection::statusReason() used with readiness ReadinessJustCreated";
+
+    return mPriv->statusReason;
+}
+
+QStringList Connection::interfaces() const
+{
+    // Different check than the others, because the optional interface getters
+    // may be used internally with the knowledge about getting the interfaces
+    // list, so we don't want this to cause warnings.
+    if (mPriv->readiness != ReadinessNotYetConnected && mPriv->readiness != ReadinessFull && mPriv->interfaces.empty())
+        warning() << "Connection::interfaces() used possibly before the list of interfaces has been received";
+    else if (mPriv->readiness == ReadinessDead)
+        warning() << "Connection::interfaces() used with readiness ReadinessDead";
+
+    return mPriv->interfaces;
+}
+
+uint Connection::aliasFlags() const
+{
+    if (mPriv->readiness != ReadinessFull)
+        warning() << "Connection::aliasFlags() used with readiness" << mPriv->readiness << "!= ReadinessFull";
+    else if (!interfaces().contains(TELEPATHY_INTERFACE_CONNECTION_INTERFACE_ALIASING))
+        warning() << "Connection::aliasFlags() used without the remote object supporting the Aliasing interface";
+
+    return mPriv->aliasFlags;
+}
+
+StatusSpecMap Connection::presenceStatuses() const
+{
+    if (mPriv->readiness != ReadinessFull)
+        warning() << "Connection::presenceStatuses() used with readiness" << mPriv->readiness << "!= ReadinessFull";
+    else if (!interfaces().contains(TELEPATHY_INTERFACE_CONNECTION_INTERFACE_PRESENCE))
+        warning() << "Connection::presenceStatuses() used without the remote object supporting the Presence interface";
+
+    return mPriv->presenceStatuses;
+}
+
+SimpleStatusSpecMap Connection::simplePresenceStatuses() const
+{
+    if (mPriv->readiness != ReadinessNotYetConnected && mPriv->readiness != ReadinessFull)
+        warning() << "Connection::simplePresenceStatuses() used with readiness" << mPriv->readiness << "not in (ReadinessNotYetConnected, ReadinessFull)";
+    else if (!interfaces().contains(TELEPATHY_INTERFACE_CONNECTION_INTERFACE_SIMPLE_PRESENCE))
+        warning() << "Connection::simplePresenceStatuses() used without the remote object supporting the SimplePresence interface";
+
+    return mPriv->simplePresenceStatuses;
+}
+
+void Connection::onStatusChanged(uint status, uint reason)
+{
+    if (status == ConnectionStatusConnected &&
+        mPriv->status != ConnectionStatusConnecting) {
+        // CMs aren't meant to go straight from Disconnected to
+        // Connected; recover by faking Connecting
+        warning() << "Non-compliant CM - went straight to CONNECTED!";
+        onStatusChanged(ConnectionStatusConnecting, reason);
+    }
+
+    debug() << "Status changed from" << mPriv->status << "to" << status << "for reason" << reason;
+
+    mPriv->status = status;
+    mPriv->statusReason = reason;
+
+    switch (status) {
+        case ConnectionStatusConnected:
+            debug() << "Performing introspection for the Connected status";
+            mPriv->introspectQueue.enqueue(&Private::introspectMain);
+            mPriv->continueIntrospection();
+            break;
+
+        case ConnectionStatusConnecting:
+            if (mPriv->readiness < ReadinessConnecting)
+                mPriv->changeReadiness(ReadinessConnecting);
+            else
+                warning() << "Got unexpected status change to Connecting";
+            break;
+
+        case ConnectionStatusDisconnected:
+            if (mPriv->readiness != ReadinessDead)
+                mPriv->changeReadiness(ReadinessDead);
+            else
+                warning() << "Got unexpected status change to Disconnected";
+            break;
+
+        default:
+            warning() << "Unknown connection status" << status;
+            break;
+    }
+}
+
+void Connection::gotStatus(QDBusPendingCallWatcher* watcher)
+{
+    QDBusPendingReply<uint> reply = *watcher;
+
+    if (reply.isError()) {
+        warning().nospace() << "GetStatus() failed with " << reply.error().name() << ": " << reply.error().message();
+        mPriv->changeReadiness(ReadinessDead);
+        return;
+    }
+
+    uint status = reply.value();
+
+    debug() << "Got connection status" << status;
+    mPriv->status = status;
+
+    // Don't do any introspection yet if the connection is in the Connecting
+    // state; the StatusChanged handler will take care of doing that, if the
+    // connection ever gets to the Connected state.
+    if (status == ConnectionStatusConnecting) {
+        debug() << "Not introspecting yet because the connection is currently Connecting";
+        mPriv->changeReadiness(ReadinessConnecting);
+        return;
+    }
+
+    if (status == ConnectionStatusDisconnected) {
+        debug() << "Performing introspection for the Disconnected status";
+        mPriv->initialIntrospection = true;
+    } else {
+        if (status != ConnectionStatusConnected) {
+            warning() << "Not performing introspection for unknown status" << status;
+            return;
+        } else {
+            debug() << "Performing introspection for the Connected status";
+        }
+    }
+
+    mPriv->introspectQueue.enqueue(&Private::introspectMain);
+    mPriv->continueIntrospection();
+}
+
+void Connection::gotInterfaces(QDBusPendingCallWatcher* watcher)
+{
+    QDBusPendingReply<QStringList> reply = *watcher;
+
+    if (!reply.isError()) {
+        mPriv->interfaces = reply.value();
+        debug() << "Got reply to GetInterfaces():" << mPriv->interfaces;
+    } else {
+        warning().nospace() << "GetInterfaces() failed with " << reply.error().name() << ": " << reply.error().message() << " - assuming no new interfaces";
+    }
+
+    for (QStringList::const_iterator i  = mPriv->interfaces.constBegin();
+                                     i != mPriv->interfaces.constEnd();
+                                     ++i) {
+        void (Private::*introspectFunc)() = 0;
+
+        if (*i == TELEPATHY_INTERFACE_CONNECTION_INTERFACE_ALIASING)
+            introspectFunc = &Private::introspectAliasing;
+        else if (*i == TELEPATHY_INTERFACE_CONNECTION_INTERFACE_PRESENCE)
+            introspectFunc = &Private::introspectPresence;
+        else if (*i == TELEPATHY_INTERFACE_CONNECTION_INTERFACE_SIMPLE_PRESENCE)
+            introspectFunc = &Private::introspectSimplePresence;
+
+        if (introspectFunc)
+            mPriv->introspectQueue.enqueue(introspectFunc);
+    }
+
+    mPriv->continueIntrospection();
+}
+
+void Connection::gotAliasFlags(QDBusPendingCallWatcher* watcher)
+{
+    QDBusPendingReply<uint> reply = *watcher;
+
+    if (!reply.isError()) {
+        mPriv->aliasFlags = static_cast<ConnectionAliasFlag>(reply.value());
+        debug().nospace() << "Got alias flags 0x" << hex << mPriv->aliasFlags;
+    } else {
+        warning().nospace() << "GetAliasFlags() failed with " << reply.error().name() << ": " << reply.error().message();
+    }
+
+    mPriv->continueIntrospection();
+}
+
+void Connection::gotStatuses(QDBusPendingCallWatcher* watcher)
+{
+    QDBusPendingReply<StatusSpecMap> reply = *watcher;
+
+    if (!reply.isError()) {
+        mPriv->presenceStatuses = reply.value();
+        debug() << "Got" << mPriv->presenceStatuses.size() << "legacy presence statuses";
+    } else {
+        warning().nospace() << "GetStatuses() failed with " << reply.error().name() << ": " << reply.error().message();
+    }
+
+    mPriv->continueIntrospection();
+}
+
+void Connection::gotSimpleStatuses(QDBusPendingCallWatcher* watcher)
+{
+    QDBusPendingReply<QDBusVariant> reply = *watcher;
+
+    if (!reply.isError()) {
+        mPriv->simplePresenceStatuses = qdbus_cast<SimpleStatusSpecMap>(reply.value().variant());
+        debug() << "Got" << mPriv->simplePresenceStatuses.size() << "simple presence statuses";
+    } else {
+        warning().nospace() << "Getting simple presence statuses failed with " << reply.error().name() << ": " << reply.error().message();
+    }
+
+    mPriv->continueIntrospection();
+}
+
+ConnectionInterface* Connection::baseInterface() const
+{
+    Q_ASSERT(mPriv->baseInterface != 0);
+    return mPriv->baseInterface;
+}
+
+PendingChannel* Connection::requestChannel(const QString& channelType, uint handleType, uint handle)
+{
+    debug() << "Requesting a Channel with type" << channelType << "and handle" << handle << "of type" << handleType;
+
+    PendingChannel* channel =
+        new PendingChannel(this, channelType, handleType, handle);
+    QDBusPendingCallWatcher* watcher =
+        new QDBusPendingCallWatcher(mPriv->baseInterface->RequestChannel(channelType, handleType, handle, true), channel);
+
+    channel->connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
+                              SLOT(onCallFinished(QDBusPendingCallWatcher*)));
+
+    return channel;
+}
+
+#if 0
+// FIXME: this is a 1:1 mapping of the method from TpPrototype, but
+// most likely what we really want as a high-level API is something
+// more analogous to tp_connection_call_when_ready() in telepathy-glib
+PendingOperation* Connection::requestConnect()
+{
+    return new PendingVoidMethodCall(this, baseInterface()->Connect());
+}
+#endif
+
+PendingOperation* Connection::requestDisconnect()
+{
+    return new PendingVoidMethodCall(this, baseInterface()->Disconnect());
+}
+
+}
+}
diff --git a/TelepathyQt4/Client/connection.h b/TelepathyQt4/Client/connection.h
new file mode 100644
index 0000000..a3191b0
--- /dev/null
+++ b/TelepathyQt4/Client/connection.h
@@ -0,0 +1,476 @@
+/*
+ * This file is part of TelepathyQt4
+ *
+ * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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 St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef _TelepathyQt4_cli_connection_h_HEADER_GUARD_
+#define _TelepathyQt4_cli_connection_h_HEADER_GUARD_
+
+/**
+ * \addtogroup clientsideproxies Client-side proxies
+ *
+ * Proxy objects representing remote service objects accessed via D-Bus.
+ *
+ * In addition to providing direct access to methods, signals and properties
+ * exported by the remote objects, some of these proxies offer features like
+ * automatic inspection of remote object capabilities, property tracking,
+ * backwards compatibility helpers for older services and other utilities.
+ */
+
+/**
+ * \defgroup clientconn Connection proxies
+ * \ingroup clientsideproxies
+ *
+ * Proxy objects representing remote Telepathy Connections and their optional
+ * interfaces.
+ */
+
+namespace Telepathy {
+namespace Client {
+class Connection;
+}
+}
+
+#include <TelepathyQt4/_gen/cli-connection.h>
+
+#include <TelepathyQt4/Client/Channel>
+#include <TelepathyQt4/Client/DBus>
+#include <TelepathyQt4/Client/DBusProxy>
+#include <TelepathyQt4/Client/OptionalInterfaceFactory>
+#include <TelepathyQt4/Client/PendingOperation>
+#include <TelepathyQt4/Constants>
+
+#include <QDBusPendingCallWatcher>
+#include <QStringList>
+
+namespace Telepathy {
+namespace Client {
+class PendingChannel;
+}
+};
+
+namespace Telepathy
+{
+namespace Client
+{
+
+/**
+ * \class Connection
+ * \ingroup clientconn
+ * \headerfile <TelepathyQt4/Client/connection.h> <TelepathyQt4/Client/Connection>
+ *
+ * High-level proxy object for accessing remote %Telepathy %Connection objects.
+ *
+ * It adds the following features compared to using ConnectionInterface
+ * directly:
+ * <ul>
+ *  <li>%Connection status tracking</li>
+ *  <li>Getting the list of supported interfaces automatically</li>
+ *  <li>Getting the alias flags automatically</li>
+ *  <li>Getting the valid presence statuses automatically</li>
+ *  <li>Shared optional interface proxy instances</li>
+ * </ul>
+ *
+ * The remote object state accessor functions on this object (status(),
+ * statusReason(), aliasFlags(), and so on) don't make any %DBus calls; instead,
+ * they return values cached from a previous introspection run. The
+ * introspection process populates their values in the most efficient way
+ * possible based on what the service implements.  Their return value is mostly
+ * undefined until the introspection process is completed; a readiness change to
+ * #ReadinessFull indicates that the introspection process is finished. See the
+ * individual accessor descriptions for details on which functions can be used
+ * in the different states.
+ */
+class Connection : public StatefulDBusProxy, private OptionalInterfaceFactory
+{
+    Q_OBJECT
+    Q_ENUMS(Readiness);
+
+public:
+    /**
+     * Describes readiness of the Connection for usage. The readiness depends
+     * on the state of the remote object. In suitable states, an asynchronous
+     * introspection process is started, and the Connection becomes more ready
+     * when that process is completed.
+     */
+    enum Readiness {
+        /**
+         * The object has just been created and introspection is still in
+         * progress. No functionality is available.
+         *
+         * The readiness can change to any other state depending on the result
+         * of the initial state query to the remote object.
+         */
+        ReadinessJustCreated = 0,
+
+        /**
+         * The remote object is in the Disconnected state and introspection
+         * relevant to that state has been completed.
+         *
+         * This state is useful for being able to set your presence status
+         * (through the SimplePresence interface) before connecting. Most other
+         * functionality is unavailable, though.
+         *
+         * The readiness can change to ReadinessConnecting and ReadinessDead.
+         */
+        ReadinessNotYetConnected = 5,
+
+        /**
+         * The remote object is in the Connecting state. Most functionality is
+         * unavailable.
+         *
+         * The readiness can change to ReadinessFull and ReadinessDead.
+         */
+        ReadinessConnecting = 10,
+
+        /**
+         * The connection is in the Connected state and all introspection
+         * has been completed. Most functionality is available.
+         *
+         * The readiness can change to ReadinessDead.
+         */
+        ReadinessFull = 15,
+
+        /**
+         * The remote object has gone into a state where it can no longer be
+         * used. No functionality is available.
+         *
+         * No further readiness changes are possible.
+         */
+        ReadinessDead = 20,
+
+        _ReadinessInvalid = 0xffff
+    };
+
+    /**
+     * Creates a Connection associated with the given object on the session bus.
+     *
+     * \param serviceName Name of the service the object is on.
+     * \param objectPath  Path to the object on the service.
+     * \param parent      Passed to the parent class constructor.
+     */
+    Connection(const QString& serviceName,
+               const QString& objectPath,
+               QObject* parent = 0);
+
+    /**
+     * Creates a Connection associated with the given object on the given bus.
+     *
+     * \param connection  The bus via which the object can be reached.
+     * \param serviceName Name of the service the object is on.
+     * \param objectPath  Path to the object on the service.
+     * \param parent      Passed to the parent class constructor.
+     */
+    Connection(const QDBusConnection& connection,
+               const QString &serviceName,
+               const QString &objectPath,
+               QObject* parent = 0);
+
+    /**
+     * Class destructor.
+     */
+    ~Connection();
+
+    /**
+     * Returns the current readiness of the Connection.
+     *
+     * \return The readiness, as defined in #Readiness.
+     */
+    Readiness readiness() const;
+
+    /**
+     * Returns the connection's status.
+     *
+     * The returned value may have changed whenever readinessChanged() is
+     * emitted. The value is valid in all states except for
+     * #ReadinessJustCreated.
+     *
+     * \return The status, as defined in #ConnectionStatus.
+     */
+    uint status() const;
+
+    /**
+     * Returns the reason for the connection's status (which is returned by
+     * status()). The validity and change rules are the same as for status().
+     *
+     * \return The reason, as defined in #ConnectionStatusReason.
+     */
+    uint statusReason() const;
+
+    /**
+     * Returns a list of optional interfaces supported by this object. The
+     * contents of the list is undefined unless the Connection has readiness
+     * #ReadinessNotYetConnected or #ReadinessFull. The returned value stays
+     * constant for the entire time the connection spends in each of these
+     * states; however interfaces might have been added to the supported set by
+     * the time #ReadinessFull is reached.
+     *
+     * \return Names of the supported interfaces.
+     */
+    QStringList interfaces() const;
+
+    /**
+     * Returns the bitwise OR of flags detailing the behavior of the Aliasing
+     * interface on the remote object.
+     *
+     * The returned value is undefined unless the Connection has readiness
+     * #ReadinessFull and the list returned by interfaces() contains
+     * %TELEPATHY_INTERFACE_CONNECTION_INTERFACE_ALIASING.
+     *
+     * \return Bitfield of flags, as specified in #ConnectionAliasFlag.
+     */
+    uint aliasFlags() const;
+
+    /**
+     * Returns a dictionary of presence statuses valid for use with the legacy
+     * Telepathy Presence interface on the remote object.
+     *
+     * The returned value is undefined unless the Connection has readiness
+     * #ReadinessFull and the list returned by interfaces() contains
+     * %TELEPATHY_INTERFACE_CONNECTION_INTERFACE_PRESENCE.
+     *
+     * \return Dictionary from string identifiers to structs for each valid status.
+     */
+    StatusSpecMap presenceStatuses() const;
+
+    /**
+     * Returns a dictionary of presence statuses valid for use with the new(er)
+     * Telepathy SimplePresence interface on the remote object.
+     *
+     * The value is undefined if the list returned by interfaces() doesn't
+     * contain %TELEPATHY_INTERFACE_CONNECTION_INTERFACE_SIMPLE_PRESENCE.
+     *
+     * The value will stay fixed for the whole time the connection stays with
+     * readiness #ReadinessNotYetConnected, but may have changed arbitrarily
+     * during the time the Connection spends in readiness #ReadinessConnecting,
+     * again staying fixed for the entire time in #ReadinessFull.
+     *
+     * \return Dictionary from string identifiers to structs for each valid
+     * status.
+     */
+    SimpleStatusSpecMap simplePresenceStatuses() const;
+
+    /**
+     * Specifies if the interface being supported by the remote object should be
+     * checked by optionalInterface() and the convenience functions for it.
+     */
+    enum InterfaceSupportedChecking
+    {
+        /**
+         * Don't return an interface instance unless it can be guaranteed that
+         * the remote object actually implements the interface.
+         */
+        CheckInterfaceSupported,
+
+        /**
+         * Return an interface instance even if it can't be verified that the
+         * remote object supports the interface.
+         */
+        BypassInterfaceCheck
+    };
+
+    /**
+     * Returns a pointer to a valid instance of a given %Connection optional
+     * interface class, associated with the same remote object the Connection is
+     * associated with, and destroyed at the same time the Connection is
+     * destroyed.
+     *
+     * If the list returned by interfaces() doesn't contain the name of the
+     * interface requested <code>0</code> is returned. This check can be
+     * bypassed by specifying #BypassInterfaceCheck for <code>check</code>, in
+     * which case a valid instance is always returned.
+     *
+     * If the object doesn't have readiness #ReadinessNotYetConnected or
+     * #ReadinessFull, the list returned by interfaces() isn't guaranteed to yet
+     * represent the full set of interfaces supported by the remote object.
+     * Hence the check might fail even if the remote object actually supports
+     * the requested interface; using #BypassInterfaceCheck is suggested when
+     * the Connection is not suitably ready.
+     *
+     * \see OptionalInterfaceFactory::interface
+     *
+     * \tparam Interface Class of the optional interface to get.
+     * \param check Should an instance be returned even if it can't be
+     *              determined that the remote object supports the
+     *              requested interface.
+     * \return Pointer to an instance of the interface class, or <code>0</code>.
+     */
+    template <class Interface>
+    inline Interface* optionalInterface(InterfaceSupportedChecking check = CheckInterfaceSupported) const
+    {
+        // Check for the remote object supporting the interface
+        QString name(Interface::staticInterfaceName());
+        if (check == CheckInterfaceSupported && !interfaces().contains(name))
+            return 0;
+
+        // If present or forced, delegate to OptionalInterfaceFactory
+        return OptionalInterfaceFactory::interface<Interface>(*baseInterface());
+    }
+
+    /**
+     * Convenience function for getting an Aliasing interface proxy.
+     *
+     * \param check Passed to optionalInterface()
+     * \return <code>optionalInterface<ConnectionInterfaceAliasingInterface>(check)</code>
+     */
+    inline ConnectionInterfaceAliasingInterface* aliasingInterface(InterfaceSupportedChecking check = CheckInterfaceSupported) const
+    {
+        return optionalInterface<ConnectionInterfaceAliasingInterface>(check);
+    }
+
+    /**
+     * Convenience function for getting an Avatars interface proxy.
+     *
+     * \param check Passed to optionalInterface()
+     * \return <code>optionalInterface<ConnectionInterfaceAvatarsInterface>(check)</code>
+     */
+    inline ConnectionInterfaceAvatarsInterface* avatarsInterface(InterfaceSupportedChecking check = CheckInterfaceSupported) const
+    {
+        return optionalInterface<ConnectionInterfaceAvatarsInterface>(check);
+    }
+
+    /**
+     * Convenience function for getting a Capabilities interface proxy.
+     *
+     * \param check Passed to optionalInterface()
+     * \return <code>optionalInterface<ConnectionInterfaceCapabilitiesInterface>(check)</code>
+     */
+    inline ConnectionInterfaceCapabilitiesInterface* capabilitiesInterface(InterfaceSupportedChecking check = CheckInterfaceSupported) const
+    {
+        return optionalInterface<ConnectionInterfaceCapabilitiesInterface>(check);
+    }
+
+    /**
+     * Convenience function for getting a Presence interface proxy.
+     *
+     * \param check Passed to optionalInterface()
+     * \return <code>optionalInterface<ConnectionInterfacePresenceInterface>(check)</code>
+     */
+    inline ConnectionInterfacePresenceInterface* presenceInterface(InterfaceSupportedChecking check = CheckInterfaceSupported) const
+    {
+        return optionalInterface<ConnectionInterfacePresenceInterface>(check);
+    }
+
+    /**
+     * Convenience function for getting a SimplePresence interface proxy.
+     *
+     * \param check Passed to optionalInterface()
+     * \return
+     * <code>optionalInterface<ConnectionInterfaceSimplePresenceInterface>(check)</code>
+     */
+    inline ConnectionInterfaceSimplePresenceInterface* simplePresenceInterface(InterfaceSupportedChecking check = CheckInterfaceSupported) const
+    {
+        return optionalInterface<ConnectionInterfaceSimplePresenceInterface>(check);
+    }
+
+    /**
+     * Convenience function for getting a Properties interface proxy. The
+     * Properties interface is not necessarily reported by the services, so a
+     * <code>check</code> parameter is not provided, and the interface is
+     * always assumed to be present.
+     *
+     * \see optionalInterface()
+     *
+     * \return
+     * <code>optionalInterface<DBus::PropertiesInterface>(BypassInterfaceCheck)</code>
+     */
+    inline DBus::PropertiesInterface* propertiesInterface() const
+    {
+        return optionalInterface<DBus::PropertiesInterface>(BypassInterfaceCheck);
+    }
+
+    /**
+     * Asynchronously requests a channel satisfying the given channel type and
+     * communicating with the contact, room, list etc. given by the handle type
+     * and handle.
+     *
+     * Upon completion, the reply to the request can be retrieved through the
+     * returned PendingChannel object. The object also provides access to the
+     * parameters with which the call was made and a signal to connect to to get
+     * notification of the request finishing processing. See the documentation
+     * for that class for more info.
+     *
+     * The returned PendingChannel object should be freed using
+     * its QObject::deleteLater() method after it is no longer used. However,
+     * all PendingChannel objects resulting from requests to a particular
+     * Connection will be freed when the Connection itself is freed. Conversely,
+     * this means that the PendingChannel object should not be used after the
+     * Connection is destroyed.
+     *
+     * \sa PendingChannel
+     *
+     * \param channelType D-Bus interface name of the channel type to request,
+     *                    such as TELEPATHY_INTERFACE_CHANNEL_TYPE_TEXT.
+     * \param handleType Type of the handle given, as specified in #HandleType.
+     * \param handle Handle specifying the remote entity to communicate with.
+     * \return Pointer to a newly constructed PendingChannel object, tracking
+     *         the progress of the request.
+     */
+    PendingChannel* requestChannel(const QString& channelType, uint handleType, uint handle);
+
+    /**
+     * Start an asynchronous request that the connection be disconnected.
+     * The returned PendingOperation object will signal the success or failure
+     * of this request; under normal circumstances, it can be expected to
+     * succeed.
+     *
+     * \return A %PendingOperation, which will emit finished when the
+     *  Disconnect D-Bus method returns.
+     */
+    PendingOperation* requestDisconnect();
+
+Q_SIGNALS:
+    /**
+     * Emitted whenever the readiness of the Connection changes.
+     *
+     * \param newReadiness The new readiness, as defined in #Readiness.
+     */
+    void readinessChanged(uint newReadiness);
+
+public:
+    /**
+     * Get the ConnectionInterface for this Connection.
+     *
+     * FIXME: This method should be protected since the convenience methods
+     * provided by this class should always be used instead. However, they
+     * haven't all been written yet.
+     *
+     * \return A pointer to the existing ConnectionInterface for this
+     *         Connection
+     */
+    ConnectionInterface* baseInterface() const;
+
+private Q_SLOTS:
+    void onStatusChanged(uint, uint);
+    void gotStatus(QDBusPendingCallWatcher* watcher);
+    void gotInterfaces(QDBusPendingCallWatcher* watcher);
+    void gotAliasFlags(QDBusPendingCallWatcher* watcher);
+    void gotStatuses(QDBusPendingCallWatcher* watcher);
+    void gotSimpleStatuses(QDBusPendingCallWatcher* watcher);
+
+private:
+    struct Private;
+    friend struct Private;
+    Private *mPriv;
+};
+
+}
+}
+
+#endif
diff --git a/TelepathyQt4/Client/dbus-proxy.cpp b/TelepathyQt4/Client/dbus-proxy.cpp
new file mode 100644
index 0000000..f98b57d
--- /dev/null
+++ b/TelepathyQt4/Client/dbus-proxy.cpp
@@ -0,0 +1,92 @@
+/*
+ * This file is part of TelepathyQt4
+ *
+ * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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 St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include "dbus-proxy.h"
+#include "dbus-proxy.moc.hpp"
+
+#include <TelepathyQt4/debug-internal.hpp>
+
+namespace Telepathy
+{
+namespace Client
+{
+
+struct DBusProxy::Private
+{
+    // Public object
+    DBusProxy& parent;
+
+    QDBusConnection dbusConnection;
+    QString busName;
+    QString objectPath;
+
+    Private(const QDBusConnection& dbusConnection, const QString& busName,
+            const QString& objectPath, DBusProxy& p)
+        : parent(p),
+          dbusConnection(dbusConnection),
+          busName(busName),
+          objectPath(objectPath)
+    {
+        debug() << "Creating new DBusProxy";
+    }
+};
+
+DBusProxy::DBusProxy(const QDBusConnection& dbusConnection,
+        const QString& busName, const QString& path, QObject* parent)
+ : QObject(parent),
+   mPriv(new Private(dbusConnection, busName, path, *this))
+{
+}
+
+DBusProxy::~DBusProxy()
+{
+    delete mPriv;
+}
+
+QDBusConnection DBusProxy::dbusConnection() const
+{
+    return mPriv->dbusConnection;
+}
+
+QString DBusProxy::objectPath() const
+{
+    return mPriv->objectPath;
+}
+
+QString DBusProxy::busName() const
+{
+    return mPriv->busName;
+}
+
+StatelessDBusProxy::StatelessDBusProxy(const QDBusConnection& dbusConnection,
+        const QString& busName, const QString& objectPath, QObject* parent)
+    : DBusProxy(dbusConnection, busName, objectPath, parent)
+{
+}
+
+StatefulDBusProxy::StatefulDBusProxy(const QDBusConnection& dbusConnection,
+        const QString& busName, const QString& objectPath, QObject* parent)
+    : DBusProxy(dbusConnection, busName, objectPath, parent)
+{
+}
+
+}
+}
diff --git a/TelepathyQt4/Client/dbus-proxy.h b/TelepathyQt4/Client/dbus-proxy.h
new file mode 100644
index 0000000..4307b41
--- /dev/null
+++ b/TelepathyQt4/Client/dbus-proxy.h
@@ -0,0 +1,190 @@
+/*
+ * This file is part of TelepathyQt4
+ *
+ * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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 St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef _TelepathyQt4_cli_dbus_proxy_h_HEADER_GUARD_
+#define _TelepathyQt4_cli_dbus_proxy_h_HEADER_GUARD_
+
+// FIXME: What groups should this be in/define?
+
+#include <QDBusAbstractInterface>
+#include <QDBusConnection>
+
+namespace Telepathy
+{
+namespace Client
+{
+
+/**
+ * \class DBusProxy
+ * \ingroup FIXME: what group is it in?
+ * \headerfile TelepathyQt4/Client/dbus-proxy.h <TelepathyQt4/Client/DBusProxy>
+ *
+ * Base class representing a remote object available over D-Bus.
+ *
+ * All TelepathyQt4 client convenience classes that wrap Telepathy interfaces
+ * inherit from this class in order to provide basic D-Bus interface
+ * information.
+ *
+ */
+class DBusProxy : public QObject
+{
+    Q_OBJECT
+
+public:
+    /**
+     * Constructor
+     */
+    DBusProxy(const QDBusConnection& dbusConnection, const QString& busName,
+            const QString& objectPath, QObject* parent = 0);
+
+    /**
+     * Destructor
+     */
+    virtual ~DBusProxy();
+
+    /**
+     * Returns the D-Bus connection through which the remote object is
+     * accessed.
+     *
+     * \return The connection the object is associated with.
+     */
+    QDBusConnection dbusConnection() const;
+
+    /**
+     * Returns the D-Bus bus name (either a unique name or a well-known
+     * name) of the service that provides the remote object.
+     *
+     * \return The service name the object is associated with.
+     */
+    QString busName() const;
+
+    /**
+     * Returns the D-Bus object path of the remote object within the service.
+     *
+     * \return The object path the object is associated with.
+     */
+    QString objectPath() const;
+
+    /**
+     * If this object is usable (has not emitted #invalidated()), returns
+     * <code>true</code>. Otherwise returns <code>false</code>.
+     *
+     * \return <code>true</code> if this object is still fully usable
+     */
+    bool isValid() const;
+
+    /**
+     * If this object is no longer usable (has emitted #invalidated()),
+     * returns the error name indicating the reason it became invalid in a
+     * machine-readable way. Otherwise, returns a null QString.
+     *
+     * \return A D-Bus error name, or QString() if this object is still valid
+     */
+    QString invalidationReason() const;
+
+    /**
+     * If this object is no longer usable (has emitted #invalidated()),
+     * returns a debugging message indicating the reason it became invalid.
+     * Otherwise, returns a null QString.
+     *
+     * \return A debugging message, or QString() if this object is still valid
+     */
+    QString invalidationMessage() const;
+
+Q_SIGNALS:
+    /**
+     * Emitted when this object is no longer usable.
+     *
+     * After this signal is emitted, any D-Bus method calls on the object
+     * will fail, but it may be possible to retrieve information that has
+     * already been retrieved and cached.
+     *
+     * \param proxy This proxy
+     * \param errorName A D-Bus error name (a string in a subset
+     *                  of ASCII, prefixed with a reversed domain name)
+     * \param errorMessage A debugging message associated with the error
+     */
+    void invalidated(DBusProxy* proxy, QString errorName,
+            QString errorMessage);
+
+private:
+    struct Private;
+    friend struct Private;
+    Private *mPriv;
+};
+
+/**
+ * \class StatelessDBusProxy
+ * \ingroup FIXME: what group is it in?
+ * \headerfile TelepathyQt4/Client/dbus-proxy.h <TelepathyQt4/Client/DBusProxy>
+ *
+ * Base class representing a remote object whose API is basically stateless.
+ * These objects can remain valid even if the service providing them exits
+ * and is restarted.
+ *
+ * Examples in Telepathy include the AccountManager, Account and
+ * ConnectionManager.
+ */
+class StatelessDBusProxy : public DBusProxy
+{
+    Q_OBJECT
+
+public:
+    StatelessDBusProxy(const QDBusConnection& dbusConnection,
+        const QString& busName, const QString& objectPath,
+        QObject* parent = 0);
+
+private:
+    struct Private;
+    friend struct Private;
+    Private *mPriv;
+};
+
+/**
+ * \class StatefulDBusProxy
+ * \ingroup FIXME: what group is it in?
+ * \headerfile TelepathyQt4/Client/dbus-proxy.h <TelepathyQt4/Client/DBusProxy>
+ *
+ * Base class representing a remote object whose API is stateful. These
+ * objects do not remain useful if the service providing them exits or
+ * crashes, so they emit #invalidated() if this happens.
+ *
+ * Examples in Telepathy include the Connection and Channel.
+ */
+class StatefulDBusProxy : public DBusProxy
+{
+    Q_OBJECT
+
+public:
+    StatefulDBusProxy(const QDBusConnection& dbusConnection,
+        const QString& busName, const QString& objectPath,
+        QObject* parent = 0);
+
+private:
+    struct Private;
+    friend struct Private;
+    Private *mPriv;
+};
+
+}
+}
+
+#endif
diff --git a/TelepathyQt4/Client/dbus.cpp b/TelepathyQt4/Client/dbus.cpp
new file mode 100644
index 0000000..39f7578
--- /dev/null
+++ b/TelepathyQt4/Client/dbus.cpp
@@ -0,0 +1,25 @@
+/*
+ * This file is part of TelepathyQt4
+ *
+ * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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 St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include "dbus.h"
+
+#include <TelepathyQt4/_gen/cli-dbus-body.hpp>
+#include <TelepathyQt4/_gen/cli-dbus.moc.hpp>
diff --git a/TelepathyQt4/Client/dbus.h b/TelepathyQt4/Client/dbus.h
new file mode 100644
index 0000000..5b130e4
--- /dev/null
+++ b/TelepathyQt4/Client/dbus.h
@@ -0,0 +1,49 @@
+/*
+ * This file is part of TelepathyQt4
+ *
+ * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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 St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef _TelepathyQt4_cli_dbus_h_HEADER_GUARD_
+#define _TelepathyQt4_cli_dbus_h_HEADER_GUARD_
+
+/**
+ * \addtogroup clientsideproxies Client-side proxies
+ *
+ * Proxy objects representing remote service objects accessed via D-Bus.
+ *
+ * In addition to providing direct access to methods, signals and properties
+ * exported by the remote objects, some of these proxies offer features like
+ * automatic inspection of remote object capabilities, property tracking,
+ * backwards compatibility helpers for older services and other utilities.
+ */
+
+/**
+ * \defgroup clientdbus Generic D-Bus proxies
+ * \ingroup clientsideproxies
+ *
+ * Proxy objects representing well-known generic D-Bus interfaces on remote
+ * objects. Note that QDBus already has QDBusConnectionInterface for accessing
+ * the bus daemon, so in the parts where there is an overlap in the
+ * functionality, using the QDBus proxy should be given consideration instead
+ * of blindly using the proxy provided here.
+ */
+
+#include <TelepathyQt4/_gen/cli-dbus.h>
+
+#endif
diff --git a/TelepathyQt4/Client/media-session-handler.cpp b/TelepathyQt4/Client/media-session-handler.cpp
new file mode 100644
index 0000000..d69529b
--- /dev/null
+++ b/TelepathyQt4/Client/media-session-handler.cpp
@@ -0,0 +1,25 @@
+/*
+ * This file is part of TelepathyQt4
+ *
+ * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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 St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include "media-session-handler.h"
+
+#include <TelepathyQt4/_gen/cli-media-session-handler-body.hpp>
+#include <TelepathyQt4/_gen/cli-media-session-handler.moc.hpp>
diff --git a/TelepathyQt4/Client/media-session-handler.h b/TelepathyQt4/Client/media-session-handler.h
new file mode 100644
index 0000000..e566c60
--- /dev/null
+++ b/TelepathyQt4/Client/media-session-handler.h
@@ -0,0 +1,45 @@
+/*
+ * This file is part of TelepathyQt4
+ *
+ * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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 St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef _TelepathyQt4_cli_media_session_handler_h_HEADER_GUARD_
+#define _TelepathyQt4_cli_media_session_handler_h_HEADER_GUARD_
+
+/**
+ * \addtogroup clientsideproxies Client-side proxies
+ *
+ * Proxy objects representing remote service objects accessed via D-Bus.
+ *
+ * In addition to providing direct access to methods, signals and properties
+ * exported by the remote objects, some of these proxies offer features like
+ * automatic inspection of remote object capabilities, property tracking,
+ * backwards compatibility helpers for older services and other utilities.
+ */
+
+/**
+ * \defgroup clientmsesh Media session handler proxies
+ * \ingroup clientsideproxies
+ *
+ * Proxy objects representing remote Telepathy MediaSessionHandler objects.
+ */
+
+#include <TelepathyQt4/_gen/cli-media-session-handler.h>
+
+#endif
diff --git a/TelepathyQt4/Client/media-stream-handler.cpp b/TelepathyQt4/Client/media-stream-handler.cpp
new file mode 100644
index 0000000..7209523
--- /dev/null
+++ b/TelepathyQt4/Client/media-stream-handler.cpp
@@ -0,0 +1,25 @@
+/*
+ * This file is part of TelepathyQt4
+ *
+ * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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 St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include "media-stream-handler.h"
+
+#include <TelepathyQt4/_gen/cli-media-stream-handler-body.hpp>
+#include <TelepathyQt4/_gen/cli-media-stream-handler.moc.hpp>
diff --git a/TelepathyQt4/Client/media-stream-handler.h b/TelepathyQt4/Client/media-stream-handler.h
new file mode 100644
index 0000000..58903b7
--- /dev/null
+++ b/TelepathyQt4/Client/media-stream-handler.h
@@ -0,0 +1,45 @@
+/*
+ * This file is part of TelepathyQt4
+ *
+ * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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 St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef _TelepathyQt4_cli_media_stream_handler_h_HEADER_GUARD_
+#define _TelepathyQt4_cli_media_stream_handler_h_HEADER_GUARD_
+
+/**
+ * \addtogroup clientsideproxies Client-side proxies
+ *
+ * Proxy objects representing remote service objects accessed via D-Bus.
+ *
+ * In addition to providing direct access to methods, signals and properties
+ * exported by the remote objects, some of these proxies offer features like
+ * automatic inspection of remote object capabilities, property tracking,
+ * backwards compatibility helpers for older services and other utilities.
+ */
+
+/**
+ * \defgroup clientmstrh Media stream handler proxies
+ * \ingroup clientsideproxies
+ *
+ * Proxy objects representing remote Telepathy MediaStreamHandler objects.
+ */
+
+#include <TelepathyQt4/_gen/cli-media-stream-handler.h>
+
+#endif
diff --git a/TelepathyQt4/Client/optional-interface-factory.cpp b/TelepathyQt4/Client/optional-interface-factory.cpp
new file mode 100644
index 0000000..2e070e4
--- /dev/null
+++ b/TelepathyQt4/Client/optional-interface-factory.cpp
@@ -0,0 +1,80 @@
+/*
+ * This file is part of TelepathyQt4
+ *
+ * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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 St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include "optional-interface-factory.h"
+
+#include <TelepathyQt4/debug-internal.hpp>
+
+#include <QMap>
+#include <QString>
+
+namespace Telepathy
+{
+namespace Client
+{
+
+struct OptionalInterfaceFactory::Private
+{
+    QMap<QString, QDBusAbstractInterface*> interfaces;
+};
+
+OptionalInterfaceFactory::OptionalInterfaceFactory()
+    : mPriv(new Private())
+{
+    debug() << "Constructing OptionalInterfaceFactory";
+}
+
+OptionalInterfaceFactory::~OptionalInterfaceFactory()
+{
+    debug() << "Destroying OptionalInterfaceFactory";
+
+    for (QMap<QString, QDBusAbstractInterface*>::iterator i = mPriv->interfaces.begin();
+                                                          i != mPriv->interfaces.end();
+                                                          ++i) {
+        debug().nospace() << " ~" << i.key();
+        delete i.value();
+    }
+
+    delete mPriv;
+}
+
+QDBusAbstractInterface* OptionalInterfaceFactory::getCached(const QString& name) const
+{
+    if (mPriv->interfaces.contains(name)) {
+        debug() << "Returning cached interface for" << name;
+        return mPriv->interfaces.value(name);
+    } else {
+        debug() << "No interface found for" << name;
+        return 0;
+    }
+}
+
+void OptionalInterfaceFactory::cache(QDBusAbstractInterface* interface) const
+{
+    QString name = interface->interface();
+    Q_ASSERT(!mPriv->interfaces.contains(name));
+
+    debug() << "Caching interface" << name;
+    mPriv->interfaces[name] = interface;
+}
+
+}
+}
diff --git a/TelepathyQt4/Client/optional-interface-factory.h b/TelepathyQt4/Client/optional-interface-factory.h
new file mode 100644
index 0000000..4a9adc0
--- /dev/null
+++ b/TelepathyQt4/Client/optional-interface-factory.h
@@ -0,0 +1,122 @@
+/*
+ * This file is part of TelepathyQt4
+ *
+ * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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 St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef _TelepathyQt4_cli_optional_interface_factory_h_HEADER_GUARD_
+#define _TelepathyQt4_cli_optional_interface_factory_h_HEADER_GUARD_
+
+/**
+ * \addtogroup clientsideproxies Client-side proxies
+ *
+ * Proxy objects representing remote service objects accessed via D-Bus.
+ *
+ * In addition to providing direct access to methods, signals and properties
+ * exported by the remote objects, some of these proxies offer features like
+ * automatic inspection of remote object capabilities, property tracking,
+ * backwards compatibility helpers for older services and other utilities.
+ */
+
+#include <QDBusAbstractInterface>
+#include <QtGlobal>
+
+namespace Telepathy
+{
+namespace Client
+{
+
+/**
+ * \class OptionalInterfaceFactory
+ * \ingroup clientsideproxies
+ * \headerfile <TelepathyQt4/Client/optional-interface-factory.h> <TelepathyQt4/Client/OptionalInterfaceFactory>
+ *
+ * Implementation helper class for high-level proxy classes willing to offer
+ * access to shared instances of interface proxies for optional interfaces.
+ *
+ * This class is included in the public API for the benefit of high-level
+ * proxies in extensions.
+ */
+class OptionalInterfaceFactory
+{
+    public:
+        /**
+         * Class constructor.
+         */
+        OptionalInterfaceFactory();
+
+        /**
+         * Class destructor.
+         *
+         * Frees all interface instances constructed by this factory.
+         */
+        ~OptionalInterfaceFactory();
+
+        /**
+         * Return a pointer to a valid instance of a interface class, associated
+         * with the same remote object as the given main interface instance. The
+         * given main interface must be of the class the optional interface is
+         * generated for (for eg. ChannelInterfaceGroupInterface this means
+         * ChannelInterface) or a subclass.
+         *
+         * First invocation of this method for a particular optional interface
+         * class will construct the instance; subsequent calls will return a
+         * pointer to the same instance.
+         *
+         * The returned instance is freed when the factory is destroyed; using
+         * it after destroying the factory will likely produce a crash. As the
+         * instance is shared, it should not be freed directly.
+         *
+         * \tparam OptionalInterface Class of the interface instance to get.
+         * \tparam MainInterface Class of the main interface.
+         * \param mainInterface Main interface instance to use.
+         * \return A pointer to an optional interface instance.
+         */
+        template <typename OptionalInterface, typename MainInterface>
+        inline OptionalInterface* interface(const MainInterface& mainInterface) const
+        {
+            // Check that the types given are both subclasses of QDBusAbstractInterface
+            QDBusAbstractInterface* mainInterfaceMustBeASubclassOfQDBusAbstractInterface = static_cast<MainInterface*>(NULL);
+            QDBusAbstractInterface* optionalInterfaceMustBeASubclassOfQDBusAbstractInterface = static_cast<OptionalInterface*>(NULL);
+            Q_UNUSED(mainInterfaceMustBeASubclassOfQDBusAbstractInterface);
+            Q_UNUSED(optionalInterfaceMustBeASubclassOfQDBusAbstractInterface);
+
+            // If there is a interface cached already, return it
+            QString name(OptionalInterface::staticInterfaceName());
+            QDBusAbstractInterface* cached = getCached(name);
+            if (cached)
+                return static_cast<OptionalInterface*>(cached);
+
+            // Otherwise, cache and return a newly constructed proxy
+            OptionalInterface* interface = new OptionalInterface(mainInterface, 0);
+            cache(interface);
+            return interface;
+        }
+
+    private:
+        QDBusAbstractInterface* getCached(const QString& name) const;
+        void cache(QDBusAbstractInterface* interface) const;
+
+        struct Private;
+        Private* mPriv;
+};
+
+}
+}
+
+#endif
diff --git a/TelepathyQt4/Client/pending-channel.cpp b/TelepathyQt4/Client/pending-channel.cpp
new file mode 100644
index 0000000..07d5e54
--- /dev/null
+++ b/TelepathyQt4/Client/pending-channel.cpp
@@ -0,0 +1,110 @@
+/*
+ * This file is part of TelepathyQt4
+ *
+ * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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 St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include "pending-channel.h"
+#include "pending-channel.moc.hpp"
+
+#include <TelepathyQt4/Client/channel.h>
+#include <TelepathyQt4/debug-internal.hpp>
+
+namespace Telepathy
+{
+namespace Client
+{
+
+struct PendingChannel::Private
+{
+    QString channelType;
+    uint handleType;
+    uint handle;
+    QDBusObjectPath objectPath;
+};
+
+PendingChannel::PendingChannel(Connection* connection, const QString& channelType, uint handleType, uint handle)
+    : PendingOperation(connection), mPriv(new Private)
+{
+    mPriv->channelType = channelType;
+    mPriv->handleType = handleType;
+    mPriv->handle = handle;
+}
+
+PendingChannel::~PendingChannel()
+{
+    delete mPriv;
+}
+
+Connection* PendingChannel::connection() const
+{
+    return qobject_cast<Connection*>(parent());
+}
+
+const QString& PendingChannel::channelType() const
+{
+    return mPriv->channelType;
+}
+
+uint PendingChannel::handleType() const
+{
+    return mPriv->handleType;
+}
+
+uint PendingChannel::handle() const
+{
+    return mPriv->handle;
+}
+
+Channel* PendingChannel::channel(QObject* parent) const
+{
+    if (!isFinished()) {
+        warning() << "PendingChannel::channel called before finished, returning 0";
+        return 0;
+    } else if (!isValid()) {
+        warning() << "PendingChannel::channel called when not valid, returning 0";
+        return 0;
+    }
+
+    Channel* channel =
+        new Channel(connection(),
+                    mPriv->objectPath.path(),
+                    parent);
+    return channel;
+}
+
+void PendingChannel::onCallFinished(QDBusPendingCallWatcher* watcher)
+{
+    QDBusPendingReply<QDBusObjectPath> reply = *watcher;
+
+    debug() << "Received reply to RequestChannel";
+
+    if (!reply.isError()) {
+        debug() << " Success: object path" << reply.value().path();
+        mPriv->objectPath = reply.value();
+        setFinished();
+    } else {
+        debug().nospace() << " Failure: error " << reply.error().name() << ": " << reply.error().message();
+        setFinishedWithError(reply.error());
+    }
+
+    watcher->deleteLater();
+}
+
+} // Telepathy::Client
+} // Telepathy
diff --git a/TelepathyQt4/Client/pending-channel.h b/TelepathyQt4/Client/pending-channel.h
new file mode 100644
index 0000000..0c93f26
--- /dev/null
+++ b/TelepathyQt4/Client/pending-channel.h
@@ -0,0 +1,136 @@
+/*
+ * This file is part of TelepathyQt4
+ *
+ * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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 St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef _TelepathyQt4_cli_pending_channel_h_HEADER_GUARD_
+#define _TelepathyQt4_cli_pending_channel_h_HEADER_GUARD_
+
+/**
+ * \addtogroup clientsideproxies Client-side proxies
+ *
+ * Proxy objects representing remote service objects accessed via D-Bus.
+ *
+ * In addition to providing direct access to methods, signals and properties
+ * exported by the remote objects, some of these proxies offer features like
+ * automatic inspection of remote object capabilities, property tracking,
+ * backwards compatibility helpers for older services and other utilities.
+ */
+
+/**
+ * \defgroup clientconn Connection proxies
+ * \ingroup clientsideproxies
+ *
+ * Proxy objects representing remote Telepathy Connections and their optional
+ * interfaces.
+ */
+
+#include <TelepathyQt4/Client/Channel>
+#include <TelepathyQt4/Client/Connection>
+#include <TelepathyQt4/Client/PendingOperation>
+#include <TelepathyQt4/Constants>
+#include <TelepathyQt4/Types>
+
+namespace Telepathy {
+namespace Client {
+class Channel;
+}
+}
+
+namespace Telepathy
+{
+namespace Client
+{
+
+/**
+ * \class PendingChannel
+ * \ingroup clientconn
+ * \headerfile <TelepathyQt4/Client/pending-channel.h> <TelepathyQt4/Client/PendingChannel>
+ *
+ * Class containing the parameters of and the reply to an asynchronous channel
+ * request. Instances of this class cannot be constructed directly; the only way
+ * to get one is to use Connection::requestChannel().
+ */
+class PendingChannel : public PendingOperation
+{
+    Q_OBJECT
+
+public:
+    /**
+     * Class destructor.
+     */
+    ~PendingChannel();
+
+    /**
+     * Returns the Connection object through which the channel request was made.
+     *
+     * \return Pointer to the Connection.
+     */
+    Connection* connection() const;
+
+    /**
+     * Returns the channel type specified in the channel request.
+     *
+     * \return The D-Bus interface name of the interface specific to the
+     *         requested channel type.
+     */
+    const QString& channelType() const;
+
+    /**
+     * Returns the handle type specified in the channel request.
+     *
+     * \return The handle type, as specified in #HandleType.
+     */
+    uint handleType() const;
+
+    /**
+     * Returns the handle specified in the channel request.
+     *
+     * \return The handle.
+     */
+    uint handle() const;
+
+    /**
+     * Returns a newly constructed Channel high-level proxy object associated
+     * with the remote channel resulting from the channel request. If isValid()
+     * returns <code>false</code>, the request has not (at least yet) completed
+     * successfully, and 0 will be returned.
+     *
+     * \param parent Passed to the Channel constructor.
+     * \return Pointer to the new Channel object.
+     */
+    Channel* channel(QObject* parent = 0) const;
+
+private Q_SLOTS:
+    void onCallFinished(QDBusPendingCallWatcher* watcher);
+
+private:
+    friend class Connection;
+
+    PendingChannel(Connection* connection, const QString& type, uint handleType, uint handle);
+
+    struct Private;
+    friend struct Private;
+    Private *mPriv;
+};
+
+} // Telepathy::Client
+} // Telepathy
+
+#endif
diff --git a/TelepathyQt4/Client/pending-operation.cpp b/TelepathyQt4/Client/pending-operation.cpp
new file mode 100644
index 0000000..c2fe9d6
--- /dev/null
+++ b/TelepathyQt4/Client/pending-operation.cpp
@@ -0,0 +1,189 @@
+/*
+ * This file is part of TelepathyQt4
+ *
+ * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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 St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include "pending-operation.h"
+#include "simple-pending-operations.h"
+#include "pending-operation.moc.hpp"
+#include "simple-pending-operations.moc.hpp"
+
+#include <TelepathyQt4/debug-internal.hpp>
+
+#include <QDBusPendingCall>
+#include <QDBusPendingCallWatcher>
+#include <QTimer>
+
+namespace Telepathy
+{
+namespace Client
+{
+
+
+struct PendingOperation::Private
+{
+    inline Private()
+      : errorName(QString()),
+        errorMessage(QString()),
+        finished(false)
+    { }
+
+    QString errorName;
+    QString errorMessage;
+    bool finished;
+};
+
+
+PendingOperation::PendingOperation(QObject* parent)
+  : QObject(parent),
+    mPriv(new Private())
+{
+}
+
+
+PendingOperation::~PendingOperation()
+{
+    if (!mPriv->finished) {
+        warning() << this
+                << "still pending when it was deleted - finished will "
+                   "never be emitted";
+    }
+
+    delete mPriv;
+}
+
+
+void PendingOperation::emitFinished()
+{
+    Q_ASSERT(mPriv->finished);
+    emit finished(this);
+    deleteLater();
+}
+
+
+void PendingOperation::setFinished()
+{
+    if (mPriv->finished) {
+        if (mPriv->errorName.isEmpty())
+            warning() << this << "trying to finish with success, but already"
+              " failed with" << errorName() << ":" << errorMessage();
+        else
+            warning() << this << "trying to finish with success, but already"
+              " succeeded";
+        return;
+    }
+
+    mPriv->finished = true;
+    Q_ASSERT(isValid());
+    QTimer::singleShot(0, this, SLOT(emitFinished()));
+}
+
+
+void PendingOperation::setFinishedWithError(const QString& name,
+        const QString& message)
+{
+    if (mPriv->finished) {
+        if (mPriv->errorName.isEmpty())
+            warning() << this << "trying to fail with" << name <<
+              "but already failed with" << errorName() << ":" <<
+              errorMessage();
+        else
+            warning() << this << "trying to fail with" << name <<
+              "but already succeeded";
+        return;
+    }
+
+    if (name.isEmpty()) {
+        warning() << this << "should be given a non-empty error name";
+        mPriv->errorName = "org.freedesktop.Telepathy.Qt4.ErrorHandlingError";
+    }
+    else {
+        mPriv->errorName = name;
+    }
+
+    mPriv->errorMessage = message;
+    mPriv->finished = true;
+    Q_ASSERT(isError());
+    QTimer::singleShot(0, this, SLOT(emitFinished()));
+}
+
+
+void PendingOperation::setFinishedWithError(const QDBusError& error)
+{
+    setFinishedWithError(error.name(), error.message());
+}
+
+
+bool PendingOperation::isValid() const
+{
+    return (mPriv->finished && mPriv->errorName.isEmpty());
+}
+
+
+bool PendingOperation::isFinished() const
+{
+    return mPriv->finished;
+}
+
+
+bool PendingOperation::isError() const
+{
+    return (mPriv->finished && !mPriv->errorName.isEmpty());
+}
+
+
+QString PendingOperation::errorName() const
+{
+    return mPriv->errorName;
+}
+
+
+QString PendingOperation::errorMessage() const
+{
+    return mPriv->errorMessage;
+}
+
+
+PendingVoidMethodCall::PendingVoidMethodCall(QObject* proxy,
+    QDBusPendingCall call)
+  : PendingOperation(proxy),
+    mPriv(0)
+{
+    connect(new QDBusPendingCallWatcher(call),
+        SIGNAL(finished(QDBusPendingCallWatcher*)),
+        this,
+        SLOT(watcherFinished(QDBusPendingCallWatcher*)));
+}
+
+
+void PendingVoidMethodCall::watcherFinished(QDBusPendingCallWatcher* watcher)
+{
+    if (watcher->isError())
+    {
+        setFinishedWithError(watcher->error());
+    }
+    else
+    {
+        setFinished();
+    }
+}
+
+
+} // Telepathy::Client
+} // Telepathy
diff --git a/TelepathyQt4/Client/pending-operation.h b/TelepathyQt4/Client/pending-operation.h
new file mode 100644
index 0000000..ada4824
--- /dev/null
+++ b/TelepathyQt4/Client/pending-operation.h
@@ -0,0 +1,176 @@
+/*
+ * This file is part of TelepathyQt4
+ *
+ * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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 St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef _TelepathyQt4_cli_pending_operation_h_HEADER_GUARD_
+#define _TelepathyQt4_cli_pending_operation_h_HEADER_GUARD_
+
+#include <QObject>
+
+class QDBusError;
+class QDBusPendingCall;
+class QDBusPendingCallWatcher;
+
+namespace Telepathy
+{
+namespace Client
+{
+
+/**
+ * Abstract base class for pending asynchronous operations.
+ *
+ * This class represents an incomplete asynchronous operation, such as a
+ * D-Bus method call. When the operation has finished, it emits
+ * #finished. The slot or slots connected to the #finished() signal may obtain
+ * additional information from the %PendingOperation.
+ *
+ * In simple cases, like a D-Bus method with no 'out' arguments or for which
+ * all 'out' arguments are to be ignored (so the possible results are
+ * success with no extra information, or failure with an error code), the
+ * trivial subclass %PendingVoidMethodCall can be used.
+ *
+ * For pending operations that produce a result, another subclass of
+ * %PendingOperation can be used, with additional methods that provide that
+ * result to the library user.
+ *
+ * After #finished() is emitted, the %PendingOperation is automatically
+ * deleted using deleteLater(), so library users must not explicitly
+ * delete this object.
+ *
+ * The design is loosely based on KDE's KJob.
+ */
+class PendingOperation : public QObject
+{
+    Q_OBJECT
+
+public:
+    virtual ~PendingOperation();
+
+    /**
+     * Returns whether or not the request has finished processing. #finished()
+     * is emitted when this changes from <code>false</code> to
+     * <code>true</code>.
+     *
+     * Equivalent to <code>(isValid() || isError())</code>.
+     *
+     * \sa finished()
+     *
+     * \return <code>true</code> if the request has finished
+     */
+    bool isFinished() const;
+
+    /**
+     * Returns whether or not the request completed successfully. If the
+     * request has not yet finished processing (isFinished() returns
+     * <code>false</code>), this cannot yet be known, and <code>false</code>
+     * will be returned.
+     *
+     * Equivalent to <code>(isFinished() && !isError())</code>.
+     *
+     * \return <code>true</code> iff the request has finished processing AND
+     *         has completed successfully.
+     */
+    bool isValid() const;
+
+    /**
+     * Returns whether or not the request resulted in an error. If the
+     * request has not yet finished processing (isFinished() returns
+     * <code>false</code>), this cannot yet be known, and <code>false</code>
+     * will be returned.
+     *
+     * Equivalent to <code>(isFinished() && !isValid())</code>.
+     *
+     * \return <code>true</code> iff the request has finished processing AND
+     *         has resulted in an error.
+     */
+    bool isError() const;
+
+    /**
+     * If #isError() would return true, returns the D-Bus error with which
+     * the operation failed. If the operation succeeded or has not yet
+     * finished, returns an empty string.
+     *
+     * \return a D-Bus error name or an empty string
+     */
+    QString errorName() const;
+
+    /**
+     * If isError() would return true, returns a debugging message associated
+     * with the error, which may be an empty string. Otherwise, return an
+     * empty string.
+     *
+     * \return a debugging message or an empty string
+     */
+    QString errorMessage() const;
+
+Q_SIGNALS:
+    /**
+     * Emitted when the pending operation finishes, i.e. when #isFinished()
+     * changes from <code>false</code> to <code>true</code>.
+     *
+     * \param operation This operation object, from which further information
+     *    may be obtained
+     */
+    void finished(Telepathy::Client::PendingOperation* operation);
+
+protected:
+    /**
+     * Protected constructor. Only subclasses of this class may be constructed
+     *
+     * \param parent The object on which this pending operation takes place
+     */
+    PendingOperation(QObject* parent);
+
+    /**
+     * Record that this pending operation has finished successfully, and
+     * emit the #finished() signal next time the event loop runs.
+     */
+    void setFinished();
+
+    /**
+     * Record that this pending operation has finished with an error, and
+     * emit the #finished() signal next time the event loop runs.
+     *
+     * \param name A D-Bus error name, which must be non-empty
+     * \param message A debugging message
+     */
+    void setFinishedWithError(const QString& name, const QString& message);
+
+    /**
+     * Record that this pending operation has finished with an error, and
+     * emit the #finished() signal next time the event loop runs.
+     *
+     * \param error A QtDBus error
+     */
+    void setFinishedWithError(const QDBusError& error);
+
+private Q_SLOTS:
+    void emitFinished();
+
+private:
+    struct Private;
+    Private *mPriv;
+};
+
+
+} // Telepathy::Client
+} // Telepathy
+
+#endif
diff --git a/TelepathyQt4/Client/properties.cpp b/TelepathyQt4/Client/properties.cpp
new file mode 100644
index 0000000..dc27378
--- /dev/null
+++ b/TelepathyQt4/Client/properties.cpp
@@ -0,0 +1,25 @@
+/*
+ * This file is part of TelepathyQt4
+ *
+ * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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 St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include "properties.h"
+
+#include <TelepathyQt4/_gen/cli-properties-body.hpp>
+#include <TelepathyQt4/_gen/cli-properties.moc.hpp>
diff --git a/TelepathyQt4/Client/properties.h b/TelepathyQt4/Client/properties.h
new file mode 100644
index 0000000..23c85ac
--- /dev/null
+++ b/TelepathyQt4/Client/properties.h
@@ -0,0 +1,46 @@
+/*
+ * This file is part of TelepathyQt4
+ *
+ * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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 St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef _TelepathyQt4_cli_properties_h_HEADER_GUARD_
+#define _TelepathyQt4_cli_properties_h_HEADER_GUARD_
+
+/**
+ * \addtogroup clientsideproxies Client-side proxies
+ *
+ * Proxy objects representing remote service objects accessed via D-Bus.
+ *
+ * In addition to providing direct access to methods, signals and properties
+ * exported by the remote objects, some of these proxies offer features like
+ * automatic inspection of remote object capabilities, property tracking,
+ * backwards compatibility helpers for older services and other utilities.
+ */
+
+/**
+ * \defgroup clientprops Telepathy Properties proxy
+ * \ingroup clientsideproxies
+ *
+ * Proxy object representing the Telepathy Properties interface on remote
+ * objects.
+ */
+
+#include <TelepathyQt4/_gen/cli-properties.h>
+
+#endif
diff --git a/TelepathyQt4/Client/simple-pending-operations.h b/TelepathyQt4/Client/simple-pending-operations.h
new file mode 100644
index 0000000..bd1f5e2
--- /dev/null
+++ b/TelepathyQt4/Client/simple-pending-operations.h
@@ -0,0 +1,111 @@
+/*
+ * This file is part of TelepathyQt4
+ *
+ * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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 St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef _TelepathyQt4_cli_pending_operations_h_HEADER_GUARD_
+#define _TelepathyQt4_cli_pending_operations_h_HEADER_GUARD_
+
+#include <QObject>
+
+#include <TelepathyQt4/Client/PendingOperation>
+
+namespace Telepathy
+{
+namespace Client
+{
+
+
+/**
+ * A %PendingOperation that is always successful.
+ */
+class PendingSuccess : public PendingOperation
+{
+    Q_OBJECT
+
+public:
+    PendingSuccess(QObject* parent)
+        : PendingOperation(parent)
+    {
+        setFinished();
+    }
+};
+
+
+/**
+ * A %PendingOperation that always fails with the error passed to the
+ * constructor.
+ */
+class PendingFailure : public PendingOperation
+{
+    Q_OBJECT
+
+public:
+    PendingFailure(QObject* parent, const QString& name,
+            const QString& message)
+        : PendingOperation(parent)
+    {
+        setFinishedWithError(name, message);
+    }
+
+    PendingFailure(QObject* parent, const QDBusError& error)
+        : PendingOperation(parent)
+    {
+        setFinishedWithError(error);
+    }
+};
+
+
+/**
+ * Generic subclass of %PendingOperation representing a pending D-Bus method
+ * call that does not return anything (or returns a result that is not
+ * interesting).
+ *
+ * Objects of this class indicate the success or failure of the method call,
+ * but if the method call succeeds, no additional information is available.
+ */
+class PendingVoidMethodCall : public PendingOperation
+{
+    Q_OBJECT
+
+public:
+    /**
+     * Constructor.
+     *
+     * \param parent The object on which this pending operation takes place
+     * \param call A pending call as returned by the auto-generated low level
+     *             Telepathy API; if the method returns anything, the return
+     *             value(s) will be ignored
+     */
+    PendingVoidMethodCall(QObject* parent, QDBusPendingCall call);
+
+private Q_SLOTS:
+    void watcherFinished(QDBusPendingCallWatcher*);
+
+private:
+    // just ABI padding at the moment
+    struct Private;
+    Private *mPriv;
+};
+
+
+} // Telepathy::Client
+} // Telepathy
+
+#endif
diff --git a/TelepathyQt4/Makefile.am b/TelepathyQt4/Makefile.am
index 2b23688..12a397a 100644
--- a/TelepathyQt4/Makefile.am
+++ b/TelepathyQt4/Makefile.am
@@ -35,19 +35,19 @@ libtelepathy_qt4_la_LIBADD = $(ALL_LIBS)
 libtelepathy_qt4_la_DEPENDENCIES = Makefile.am
 
 libtelepathy_qt4_la_SOURCES = \
-    cli-account.cpp \
-    cli-account-manager.cpp \
-    cli-channel.cpp \
-    cli-connection.cpp \
-    cli-connection-manager.cpp \
-    cli-dbus.cpp \
-    cli-dbus-proxy.cpp \
-    cli-media-session-handler.cpp \
-    cli-media-stream-handler.cpp \
-    cli-optional-interface-factory.cpp \
-    cli-pending-channel.cpp \
-    cli-pending-operation.cpp \
-    cli-properties.cpp \
+    Client/account.cpp \
+    Client/account-manager.cpp \
+    Client/channel.cpp \
+    Client/connection.cpp \
+    Client/connection-manager.cpp \
+    Client/dbus.cpp \
+    Client/dbus-proxy.cpp \
+    Client/media-session-handler.cpp \
+    Client/media-stream-handler.cpp \
+    Client/optional-interface-factory.cpp \
+    Client/pending-channel.cpp \
+    Client/pending-operation.cpp \
+    Client/properties.cpp \
     debug.cpp \
     debug-internal.hpp \
     key-file.cpp \
@@ -75,13 +75,13 @@ nodist_libtelepathy_qt4_la_SOURCES = \
     _gen/cli-properties-body.hpp \
     _gen/cli-properties.moc.hpp \
     _gen/types-body.hpp \
-    cli-channel.moc.hpp \
-    cli-connection.moc.hpp \
-    cli-connection-manager.moc.hpp \
-    cli-dbus-proxy.moc.hpp \
-    cli-pending-channel.moc.hpp \
-    cli-pending-operation.moc.hpp \
-    cli-simple-pending-operations.moc.hpp
+    Client/channel.moc.hpp \
+    Client/connection.moc.hpp \
+    Client/connection-manager.moc.hpp \
+    Client/dbus-proxy.moc.hpp \
+    Client/pending-channel.moc.hpp \
+    Client/pending-operation.moc.hpp \
+    Client/simple-pending-operations.moc.hpp
 
 tpqt4include_HEADERS = \
     Constants \
@@ -89,20 +89,6 @@ tpqt4include_HEADERS = \
     KeyFile \
     ManagerFile \
     Types \
-    cli-account.h \
-    cli-account-manager.h \
-    cli-channel.h \
-    cli-connection.h \
-    cli-connection-manager.h \
-    cli-dbus.h \
-    cli-dbus-proxy.h \
-    cli-media-session-handler.h \
-    cli-media-stream-handler.h \
-    cli-optional-interface-factory.h \
-    cli-pending-channel.h \
-    cli-pending-operation.h \
-    cli-properties.h \
-    cli-simple-pending-operations.h \
     constants.h \
     debug.h \
     key-file.h \
@@ -110,6 +96,7 @@ tpqt4include_HEADERS = \
     types.h
 
 tpqt4clientinclude_HEADERS = \
+    Client/Account \
     Client/AccountManager \
     Client/Channel \
     Client/Connection \
@@ -119,11 +106,28 @@ tpqt4clientinclude_HEADERS = \
     Client/MediaSessionHandler \
     Client/MediaStreamHandler \
     Client/OptionalInterfaceFactory \
+    Client/PendingChannel \
     Client/PendingFailure \
     Client/PendingOperation \
     Client/PendingSuccess \
     Client/PendingVoidMethodCall \
-    Client/Properties
+    Client/Properties \
+    Client/StatelessDBusProxy \
+    Client/StatefulDBusProxy \
+    Client/account.h \
+    Client/account-manager.h \
+    Client/channel.h \
+    Client/connection.h \
+    Client/connection-manager.h \
+    Client/dbus.h \
+    Client/dbus-proxy.h \
+    Client/media-session-handler.h \
+    Client/media-stream-handler.h \
+    Client/optional-interface-factory.h \
+    Client/pending-channel.h \
+    Client/pending-operation.h \
+    Client/properties.h \
+    Client/simple-pending-operations.h
 
 nodist_geninclude_HEADERS = \
     _gen/cli-account.h \
@@ -262,7 +266,7 @@ _gen/cli-%.h _gen/cli-%-body.hpp: _gen/spec-%.xml \
 		--typesnamespace='Telepathy' \
 		--headerfile=_gen/cli-$*.h \
 		--implfile=_gen/cli-$*-body.hpp \
-		--realinclude='TelepathyQt4/cli-$*.h' \
+		--realinclude='TelepathyQt4/Client/$*.h' \
 		--prettyinclude='TelepathyQt4/Client/'$$prettyinclude \
 		--specxml=_gen/stable-spec.xml \
 		--ifacexml=$< \
diff --git a/TelepathyQt4/Prototype/Account.cpp b/TelepathyQt4/Prototype/Account.cpp
index a85c0bc..b2d19d5 100644
--- a/TelepathyQt4/Prototype/Account.cpp
+++ b/TelepathyQt4/Prototype/Account.cpp
@@ -25,6 +25,7 @@
 #include <QDebug>
 #include <QMetaProperty>
 
+#include <TelepathyQt4/Client/Account>
 #include <TelepathyQt4/Client/AccountManager>
 
 #include <TelepathyQt4/Prototype/Connection.h>
diff --git a/TelepathyQt4/cli-account-manager.cpp b/TelepathyQt4/cli-account-manager.cpp
deleted file mode 100644
index 04150fb..0000000
--- a/TelepathyQt4/cli-account-manager.cpp
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * This file is part of TelepathyQt4
- *
- * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
- * Copyright (C) 2008 Nokia Corporation
- *
- * 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.
- *
- * 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.
- *
- * 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 St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#include "cli-account-manager.h"
-
-#include <TelepathyQt4/_gen/cli-account-manager.moc.hpp>
-#include <TelepathyQt4/_gen/cli-account-manager-body.hpp>
diff --git a/TelepathyQt4/cli-account-manager.h b/TelepathyQt4/cli-account-manager.h
deleted file mode 100644
index ff5fe85..0000000
--- a/TelepathyQt4/cli-account-manager.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * This file is part of TelepathyQt4
- *
- * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
- * Copyright (C) 2008 Nokia Corporation
- *
- * 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.
- *
- * 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.
- *
- * 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 St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#ifndef _TelepathyQt4_cli_account_manager_h_HEADER_GUARD_
-#define _TelepathyQt4_cli_account_manager_h_HEADER_GUARD_
-
-/**
- * \addtogroup clientsideproxies Client-side proxies
- *
- * Proxy objects representing remote service objects accessed via D-Bus.
- *
- * In addition to providing direct access to methods, signals and properties
- * exported by the remote objects, some of these proxies offer features like
- * automatic inspection of remote object capabilities, property tracking,
- * backwards compatibility helpers for older services and other utilities.
- */
-
-/**
- * \defgroup clientaccount Account and Account Manager proxies
- * \ingroup clientsideproxies
- *
- * ...
- */
-
-#include "TelepathyQt4/_gen/cli-account-manager.h"
-
-#if 0
-#include "TelepathyQt4/_gen/cli-account-manager-interface-creation.h"
-#include "TelepathyQt4/_gen/cli-account-manager-interface-query.h"
-#endif
-
-#endif
diff --git a/TelepathyQt4/cli-account.cpp b/TelepathyQt4/cli-account.cpp
deleted file mode 100644
index 08adfe3..0000000
--- a/TelepathyQt4/cli-account.cpp
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * This file is part of TelepathyQt4
- *
- * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
- * Copyright (C) 2008 Nokia Corporation
- *
- * 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.
- *
- * 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.
- *
- * 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 St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#include "cli-account.h"
-
-#include <TelepathyQt4/_gen/cli-account-body.hpp>
-#include <TelepathyQt4/_gen/cli-account.moc.hpp>
diff --git a/TelepathyQt4/cli-account.h b/TelepathyQt4/cli-account.h
deleted file mode 100644
index a39733b..0000000
--- a/TelepathyQt4/cli-account.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * This file is part of TelepathyQt4
- *
- * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
- * Copyright (C) 2008 Nokia Corporation
- *
- * 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.
- *
- * 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.
- *
- * 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 St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#ifndef _TelepathyQt4_cli_account_h_HEADER_GUARD_
-#define _TelepathyQt4_cli_account_h_HEADER_GUARD_
-
-/**
- * \addtogroup clientsideproxies Client-side proxies
- *
- * Proxy objects representing remote service objects accessed via D-Bus.
- *
- * In addition to providing direct access to methods, signals and properties
- * exported by the remote objects, some of these proxies offer features like
- * automatic inspection of remote object capabilities, property tracking,
- * backwards compatibility helpers for older services and other utilities.
- */
-
-/* See cli-account-manager.h for doxygen */
-
-#include "TelepathyQt4/_gen/cli-account.h"
-
-#if 0
-#include "TelepathyQt4/_gen/cli-account-interface-avatar.h"
-#endif
-
-#endif
-
diff --git a/TelepathyQt4/cli-channel.cpp b/TelepathyQt4/cli-channel.cpp
deleted file mode 100644
index 545ade7..0000000
--- a/TelepathyQt4/cli-channel.cpp
+++ /dev/null
@@ -1,931 +0,0 @@
-/*
- * This file is part of TelepathyQt4
- *
- * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
- * Copyright (C) 2008 Nokia Corporation
- *
- * 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.
- *
- * 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.
- *
- * 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 St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#include "cli-channel.h"
-
-#include "_gen/cli-channel-body.hpp"
-#include "_gen/cli-channel.moc.hpp"
-#include "cli-channel.moc.hpp"
-
-#include <QQueue>
-
-#include "cli-dbus.h"
-#include "constants.h"
-#include "debug-internal.hpp"
-
-namespace Telepathy
-{
-namespace Client
-{
-
-struct Channel::Private
-{
-    // Public object
-    Channel& parent;
-
-    // Instance of generated interface class
-    ChannelInterface* baseInterface;
-
-    // Owning connection
-    Connection* connection;
-
-    // Optional interface proxies
-    ChannelInterfaceGroupInterface* group;
-    DBus::PropertiesInterface* properties;
-
-    // Introspection
-    Readiness readiness;
-    QStringList interfaces;
-    QQueue<void (Private::*)()> introspectQueue;
-
-    // Introspected properties
-
-    // Main interface
-    QString channelType;
-    uint targetHandleType;
-    uint targetHandle;
-
-    // Group flags
-    uint groupFlags;
-
-    // Group members
-    bool groupHaveMembers;
-    QSet<uint> groupMembers;
-    GroupMemberChangeInfoMap groupLocalPending;
-    QSet<uint> groupRemotePending;
-
-    // Group handle owners
-    bool groupAreHandleOwnersAvailable;
-    HandleOwnerMap groupHandleOwners;
-
-    // Group self handle
-    bool groupIsSelfHandleTracked;
-    uint groupSelfHandle;
-
-    // Group remove info
-    GroupMemberChangeInfo groupSelfRemoveInfo;
-
-    Private(Channel& parent, Connection* connection)
-        : parent(parent)
-    {
-        debug() << "Creating new Channel";
-
-        baseInterface = 0;
-        group = 0;
-        properties = 0;
-        readiness = ReadinessJustCreated;
-        targetHandleType = 0;
-        targetHandle = 0;
-
-        groupFlags = 0;
-        groupHaveMembers = false;
-        groupAreHandleOwnersAvailable = false;
-        groupIsSelfHandleTracked = false;
-        groupSelfHandle = 0;
-
-        debug() << " Connecting to Channel::Closed()";
-        parent.connect(baseInterface,
-                       SIGNAL(Closed()),
-                       SLOT(onClosed()));
-
-        debug() << " Connection to owning connection's lifetime signals";
-        parent.connect(connection,
-                       SIGNAL(readinessChanged(uint)),
-                       SLOT(onConnectionReadinessChanged(uint)));
-
-        parent.connect(connection,
-                       SIGNAL(destroyed()),
-                       SLOT(onConnectionDestroyed()));
-
-        if (connection->readiness() == Connection::ReadinessDead) {
-            warning() << "Connection given as the owner for a Channel was already dead! Channel will be stillborn.";
-            readiness = ReadinessDead;
-        }
-
-        introspectQueue.enqueue(&Private::introspectMain);
-    }
-
-    void introspectMain()
-    {
-        if (!properties) {
-            properties = parent.propertiesInterface();
-            Q_ASSERT(properties != 0);
-        }
-
-        debug() << "Calling Properties::GetAll(Channel)";
-        QDBusPendingCallWatcher* watcher =
-            new QDBusPendingCallWatcher(
-                    properties->GetAll(TELEPATHY_INTERFACE_CHANNEL), &parent);
-        parent.connect(watcher,
-                       SIGNAL(finished(QDBusPendingCallWatcher*)),
-                       SLOT(gotMainProperties(QDBusPendingCallWatcher*)));
-    }
-
-    void introspectMainFallbackChannelType()
-    {
-        debug() << "Calling Channel::GetChannelType()";
-        QDBusPendingCallWatcher* watcher =
-            new QDBusPendingCallWatcher(baseInterface->GetChannelType(), &parent);
-        parent.connect(watcher,
-                       SIGNAL(finished(QDBusPendingCallWatcher*)),
-                       SLOT(gotChannelType(QDBusPendingCallWatcher*)));
-    }
-
-    void introspectMainFallbackHandle()
-    {
-        debug() << "Calling Channel::GetHandle()";
-        QDBusPendingCallWatcher* watcher =
-            new QDBusPendingCallWatcher(baseInterface->GetHandle(), &parent);
-        parent.connect(watcher,
-                       SIGNAL(finished(QDBusPendingCallWatcher*)),
-                       SLOT(gotHandle(QDBusPendingCallWatcher*)));
-    }
-
-    void introspectMainFallbackInterfaces()
-    {
-        debug() << "Calling Channel::GetInterfaces()";
-        QDBusPendingCallWatcher* watcher =
-            new QDBusPendingCallWatcher(baseInterface->GetInterfaces(), &parent);
-        parent.connect(watcher,
-                       SIGNAL(finished(QDBusPendingCallWatcher*)),
-                       SLOT(gotInterfaces(QDBusPendingCallWatcher*)));
-    }
-
-    void introspectGroup()
-    {
-        Q_ASSERT(properties != 0);
-
-        if (!group) {
-            group = parent.groupInterface();
-            Q_ASSERT(group != 0);
-        }
-
-        debug() << "Connecting to Channel.Interface.Group::GroupFlagsChanged";
-        parent.connect(group,
-                       SIGNAL(GroupFlagsChanged(uint, uint)),
-                       SLOT(onGroupFlagsChanged(uint, uint)));
-
-        debug() << "Connecting to Channel.Interface.Group::MembersChanged";
-        parent.connect(group,
-                       SIGNAL(MembersChanged(const QString&, const Telepathy::UIntList&, const Telepathy::UIntList&, const Telepathy::UIntList&, const Telepathy::UIntList&, uint, uint)),
-                       SLOT(onMembersChanged(const QString&, const Telepathy::UIntList&, const Telepathy::UIntList&, const Telepathy::UIntList&, const Telepathy::UIntList&, uint, uint)));
-
-        debug() << "Connecting to Channel.Interface.Group::HandleOwnersChanged";
-        parent.connect(group,
-                       SIGNAL(HandleOwnersChanged(const Telepathy::HandleOwnerMap&, const Telepathy::UIntList&)),
-                       SLOT(onHandleOwnersChanged(const Telepathy::HandleOwnerMap&, const Telepathy::UIntList&)));
-
-        debug() << "Connecting to Channel.Interface.Group::SelfHandleChanged";
-        parent.connect(group,
-                       SIGNAL(SelfHandleChanged(uint)),
-                       SLOT(onSelfHandleChanged(uint)));
-
-        debug() << "Calling Properties::GetAll(Channel.Interface.Group)";
-        QDBusPendingCallWatcher* watcher =
-            new QDBusPendingCallWatcher(
-                    properties->GetAll(TELEPATHY_INTERFACE_CHANNEL_INTERFACE_GROUP), &parent);
-        parent.connect(watcher,
-                       SIGNAL(finished(QDBusPendingCallWatcher*)),
-                       SLOT(gotGroupProperties(QDBusPendingCallWatcher*)));
-    }
-
-    void introspectGroupFallbackFlags()
-    {
-        Q_ASSERT(group != 0);
-
-        debug() << "Calling Channel.Interface.Group::GetGroupFlags()";
-        QDBusPendingCallWatcher* watcher =
-            new QDBusPendingCallWatcher(group->GetGroupFlags(), &parent);
-        parent.connect(watcher,
-                       SIGNAL(finished(QDBusPendingCallWatcher*)),
-                       SLOT(gotGroupFlags(QDBusPendingCallWatcher*)));
-    }
-
-    void introspectGroupFallbackMembers()
-    {
-        Q_ASSERT(group != 0);
-
-        debug() << "Calling Channel.Interface.Group::GetAllMembers()";
-        QDBusPendingCallWatcher* watcher =
-            new QDBusPendingCallWatcher(group->GetAllMembers(), &parent);
-        parent.connect(watcher,
-                       SIGNAL(finished(QDBusPendingCallWatcher*)),
-                       SLOT(gotAllMembers(QDBusPendingCallWatcher*)));
-    }
-
-    void introspectGroupFallbackLocalPending()
-    {
-        Q_ASSERT(group != 0);
-
-        debug() << "Calling Channel.Interface.Group::GetLocalPendingMembersWithInfo()";
-        QDBusPendingCallWatcher* watcher =
-            new QDBusPendingCallWatcher(group->GetLocalPendingMembersWithInfo(), &parent);
-        parent.connect(watcher,
-                       SIGNAL(finished(QDBusPendingCallWatcher*)),
-                       SLOT(gotLocalPending(QDBusPendingCallWatcher*)));
-    }
-
-    void introspectGroupFallbackSelfHandle()
-    {
-        Q_ASSERT(group != 0);
-
-        debug() << "Calling Channel.Interface.Group::GetSelfHandle()";
-        QDBusPendingCallWatcher* watcher =
-            new QDBusPendingCallWatcher(group->GetSelfHandle(), &parent);
-        parent.connect(watcher,
-                       SIGNAL(finished(QDBusPendingCallWatcher*)),
-                       SLOT(gotSelfHandle(QDBusPendingCallWatcher*)));
-    }
-
-    void continueIntrospection()
-    {
-        if (readiness < ReadinessFull) {
-            if (introspectQueue.isEmpty()) {
-                changeReadiness(ReadinessFull);
-            } else {
-                (this->*introspectQueue.dequeue())();
-            }
-        }
-    }
-
-    void extract0177MainProps(const QVariantMap& props)
-    {
-        bool haveProps = props.size() >= 4
-                      && props.contains("ChannelType") && !qdbus_cast<QString>(props["ChannelType"]).isEmpty()
-                      && props.contains("Interfaces")
-                      && props.contains("TargetHandle")
-                      && props.contains("TargetHandleType");
-
-        if (!haveProps) {
-            warning() << " Properties specified in 0.17.7 not found";
-
-            introspectQueue.enqueue(&Private::introspectMainFallbackChannelType);
-            introspectQueue.enqueue(&Private::introspectMainFallbackHandle);
-            introspectQueue.enqueue(&Private::introspectMainFallbackInterfaces);
-        } else {
-            debug() << " Found properties specified in 0.17.7";
-
-            channelType = qdbus_cast<QString>(props["ChannelType"]);
-            interfaces = qdbus_cast<QStringList>(props["Interfaces"]);
-            targetHandle = qdbus_cast<uint>(props["TargetHandle"]);
-            targetHandleType = qdbus_cast<uint>(props["TargetHandleType"]);
-
-            nowHaveInterfaces();
-        }
-    }
-
-    void extract0176GroupProps(const QVariantMap& props)
-    {
-        bool haveProps = props.size() >= 6
-                      && (props.contains("GroupFlags") && (qdbus_cast<uint>(props["GroupFlags"]) & ChannelGroupFlagProperties))
-                      && props.contains("HandleOwners")
-                      && props.contains("LocalPendingMembers")
-                      && props.contains("Members")
-                      && props.contains("RemotePendingMembers")
-                      && props.contains("SelfHandle");
-
-        if (!haveProps) {
-            warning() << " Properties specified in 0.17.6 not found";
-            warning() << "  Handle owners and self handle tracking disabled";
-
-            introspectQueue.enqueue(&Private::introspectGroupFallbackFlags);
-            introspectQueue.enqueue(&Private::introspectGroupFallbackMembers);
-            introspectQueue.enqueue(&Private::introspectGroupFallbackLocalPending);
-            introspectQueue.enqueue(&Private::introspectGroupFallbackSelfHandle);
-        } else {
-            debug() << " Found properties specified in 0.17.6";
-
-            groupHaveMembers = true;
-            groupAreHandleOwnersAvailable = true;
-            groupIsSelfHandleTracked = true;
-
-            groupFlags = qdbus_cast<uint>(props["GroupFlags"]);
-            groupHandleOwners = qdbus_cast<HandleOwnerMap>(props["HandleOwners"]);
-            groupMembers = QSet<uint>::fromList(qdbus_cast<UIntList>(props["Members"]));
-            groupRemotePending = QSet<uint>::fromList(qdbus_cast<UIntList>(props["RemotePendingMembers"]));
-            groupSelfHandle = qdbus_cast<uint>(props["SelfHandle"]);
-
-            foreach (LocalPendingInfo info, qdbus_cast<LocalPendingInfoList>(props["LocalPendingMembers"])) {
-                groupLocalPending[info.toBeAdded] =
-                    GroupMemberChangeInfo(info.actor, info.reason, info.message);
-            }
-        }
-    }
-
-    void nowHaveInterfaces()
-    {
-        debug() << "Channel has" << interfaces.size() << "optional interfaces:" << interfaces;
-
-        for (QStringList::const_iterator i = interfaces.begin();
-                                         i != interfaces.end();
-                                         ++i) {
-            if (*i == TELEPATHY_INTERFACE_CHANNEL_INTERFACE_GROUP) {
-                introspectQueue.enqueue(&Private::introspectGroup);
-            }
-        }
-    }
-
-    void changeReadiness(Readiness newReadiness)
-    {
-        Q_ASSERT(newReadiness != readiness);
-        switch (readiness) {
-            case ReadinessJustCreated:
-                // We don't allow ReadinessClosed to be reached without ReadinessFull
-                // being reached at some point first.
-                Q_ASSERT((newReadiness == ReadinessFull) || (newReadiness == ReadinessDead));
-                break;
-            case ReadinessFull:
-                Q_ASSERT((newReadiness == ReadinessDead) || (newReadiness == ReadinessClosed));
-                break;
-            case ReadinessDead:
-            case ReadinessClosed:
-            default:
-                Q_ASSERT(false);
-                break;
-        }
-
-        debug() << "Channel readiness changed from" << readiness << "to" << newReadiness;
-
-        if (newReadiness == ReadinessFull) {
-            debug() << "Channel fully ready";
-            debug() << " Channel type" << channelType;
-            debug() << " Target handle" << targetHandle;
-            debug() << " Target handle type" << targetHandleType;
-
-            if (interfaces.contains(TELEPATHY_INTERFACE_CHANNEL_INTERFACE_GROUP)) {
-                debug() << " Group: flags" << groupFlags;
-                if (groupAreHandleOwnersAvailable)
-                    debug() << " Group: Number of handle owner mappings" << groupHandleOwners.size();
-                else
-                    debug() << " Group: No handle owners property present";
-                debug() << " Group: Number of current members" << groupMembers.size();
-                debug() << " Group: Number of local pending members" << groupLocalPending.size();
-                debug() << " Group: Number of remote pending members" << groupRemotePending.size();
-                debug() << " Group: Self handle" << groupSelfHandle << "tracked:" << (groupIsSelfHandleTracked ? "yes" : "no");
-            }
-        } else {
-            Q_ASSERT((newReadiness == ReadinessDead) || (newReadiness == ReadinessClosed));
-
-            debug() << "R.I.P. Channel.";
-
-            if (groupSelfRemoveInfo.isValid()) {
-                debug() << " Group: removed by  " << groupSelfRemoveInfo.actor();
-                debug() << "        because of  " << groupSelfRemoveInfo.reason();
-                debug() << "        with message" << groupSelfRemoveInfo.message();
-            }
-        }
-
-        readiness = newReadiness;
-        emit parent.readinessChanged(newReadiness);
-    }
-};
-
-Channel::Channel(Connection* connection,
-                 const QString& objectPath,
-                 QObject* parent)
-  : StatefulDBusProxy(connection->dbusConnection(), connection->busName(),
-            objectPath, parent),
-    mPriv(new Private(*this, connection))
-{
-    mPriv->baseInterface = new ChannelInterface(this->dbusConnection(),
-            this->busName(), this->objectPath(), this);
-
-    // Introspection continued here so mPriv will be initialized (unlike if we
-    // continued it from the Private constructor)
-    mPriv->continueIntrospection();
-}
-
-Channel::~Channel()
-{
-    delete mPriv;
-}
-
-Connection* Channel::connection() const
-{
-    return mPriv->connection;
-}
-
-Channel::Readiness Channel::readiness() const
-{
-    return mPriv->readiness;
-}
-
-QStringList Channel::interfaces() const
-{
-    // Different check than the others, because the optional interface getters
-    // may be used internally with the knowledge about getting the interfaces
-    // list, so we don't want this to cause warnings.
-    if (mPriv->readiness < ReadinessFull && mPriv->interfaces.empty())
-        warning() << "Channel::interfaces() used possibly before the list of interfaces has been received";
-    else if (mPriv->readiness == ReadinessDead)
-        warning() << "Channel::interfaces() used with readiness ReadinessDead";
-    else if (mPriv->readiness == ReadinessClosed)
-        warning() << "Channel::interfaces() used with readiness ReadinessClosed";
-
-    return mPriv->interfaces;
-}
-
-QString Channel::channelType() const
-{
-    // Similarly, we don't want warnings triggered when using the type interface
-    // proxies internally.
-    if (mPriv->readiness < ReadinessFull && mPriv->channelType.isEmpty())
-        warning() << "Channel::channelType() before the channel type has been received";
-    else if (mPriv->readiness == ReadinessDead)
-        warning() << "Channel::channelType() used with readiness ReadinessDead";
-    // Channel type will still be valid if the channel has been closed after
-    // introspection completed successfully.
-    // else if (mPriv->readiness == ReadinessClosed)
-    //    warning() << "Channel::channelType() used with readiness ReadinessClosed";
-
-    return mPriv->channelType;
-}
-
-uint Channel::targetHandleType() const
-{
-    if (mPriv->readiness != ReadinessFull)
-        warning() << "Channel::targetHandleType() used with readiness" << mPriv->readiness << "!= ReadinessFull";
-
-    return mPriv->targetHandleType;
-}
-
-uint Channel::targetHandle() const
-{
-    if (mPriv->readiness != ReadinessFull)
-        warning() << "Channel::targetHandle() used with readiness" << mPriv->readiness << "!= ReadinessFull";
-
-    return mPriv->targetHandle;
-}
-
-QDBusPendingReply<> Channel::close()
-{
-    // Closing a channel does not make sense if it is already dead or closed.
-    if ((mPriv->readiness != ReadinessDead) && (mPriv->readiness != ReadinessClosed))
-        return mPriv->baseInterface->Close();
-
-    // If the channel is in a readiness where it doesn't make sense to be
-    // closed, we emit a warning and return an error QDBusPendingReply.
-    warning() << "Channel::close() used with readiness" << mPriv->readiness;
-
-    return QDBusPendingReply<>(QDBusMessage::createError(
-            "TELEPATHY_ERROR_NOT_AVAILABLE", "Attempted to close an already dead or closed channel"));
-}
-
-uint Channel::groupFlags() const
-{
-    if (mPriv->readiness != ReadinessFull)
-        warning() << "Channel::groupFlags() used with readiness" << mPriv->readiness << "!= ReadinessFull";
-    else if (!mPriv->interfaces.contains(TELEPATHY_INTERFACE_CHANNEL_INTERFACE_GROUP))
-        warning() << "Channel::groupFlags() used with no group interface";
-
-    return mPriv->groupFlags;
-}
-
-QSet<uint> Channel::groupMembers() const
-{
-    if (mPriv->readiness != ReadinessFull)
-        warning() << "Channel::groupMembers() used with readiness" << mPriv->readiness << "!= ReadinessFull";
-    else if (!mPriv->interfaces.contains(TELEPATHY_INTERFACE_CHANNEL_INTERFACE_GROUP))
-        warning() << "Channel::groupMembers() used with no group interface";
-
-    return mPriv->groupMembers;
-}
-
-Channel::GroupMemberChangeInfoMap Channel::groupLocalPending() const
-{
-    if (mPriv->readiness != ReadinessFull)
-        warning() << "Channel::groupLocalPending() used with readiness" << mPriv->readiness << "!= ReadinessFull";
-    else if (!mPriv->interfaces.contains(TELEPATHY_INTERFACE_CHANNEL_INTERFACE_GROUP))
-        warning() << "Channel::groupLocalPending() used with no group interface";
-
-    return mPriv->groupLocalPending;
-}
-
-QSet<uint> Channel::groupRemotePending() const
-{
-    if (mPriv->readiness != ReadinessFull)
-        warning() << "Channel::groupRemotePending() used with readiness" << mPriv->readiness << "!= ReadinessFull";
-    else if (!mPriv->interfaces.contains(TELEPATHY_INTERFACE_CHANNEL_INTERFACE_GROUP))
-        warning() << "Channel::groupRemotePending() used with no group interface";
-
-    return mPriv->groupRemotePending;
-}
-
-bool Channel::groupAreHandleOwnersAvailable() const
-{
-    if (mPriv->readiness != ReadinessFull)
-        warning() << "Channel::groupAreHandleOwnersAvailable() used with readiness" << mPriv->readiness << "!= ReadinessFull";
-    else if (!mPriv->interfaces.contains(TELEPATHY_INTERFACE_CHANNEL_INTERFACE_GROUP))
-        warning() << "Channel::groupAreHandleOwnersAvailable() used with no group interface";
-
-    return mPriv->groupAreHandleOwnersAvailable;
-}
-
-HandleOwnerMap Channel::groupHandleOwners() const
-{
-    if (mPriv->readiness != ReadinessFull)
-        warning() << "Channel::groupHandleOwners() used with readiness" << mPriv->readiness << "!= ReadinessFull";
-    else if (!mPriv->interfaces.contains(TELEPATHY_INTERFACE_CHANNEL_INTERFACE_GROUP))
-        warning() << "Channel::groupAreHandleOwnersAvailable() used with no group interface";
-    else if (!groupAreHandleOwnersAvailable())
-        warning() << "Channel::areHandleOwnersAvailable() used, but handle owners not available";
-
-    return mPriv->groupHandleOwners;
-}
-
-bool Channel::groupIsSelfHandleTracked() const
-{
-    if (mPriv->readiness != ReadinessFull)
-        warning() << "Channel::isSelfHandleTracked() used with readiness" << mPriv->readiness << "!= ReadinessFull";
-    else if (!mPriv->interfaces.contains(TELEPATHY_INTERFACE_CHANNEL_INTERFACE_GROUP))
-        warning() << "Channel::groupIsSelfHandleTracked() used with no group interface";
-
-    return mPriv->groupIsSelfHandleTracked;
-}
-
-uint Channel::groupSelfHandle() const
-{
-    if (mPriv->readiness != ReadinessFull)
-        warning() << "Channel::groupSelfHandle() used with readiness" << mPriv->readiness << "!= ReadinessFull";
-    else if (!mPriv->interfaces.contains(TELEPATHY_INTERFACE_CHANNEL_INTERFACE_GROUP))
-        warning() << "Channel::groupSelfHandle() used with no group interface";
-
-    return mPriv->groupSelfHandle;
-}
-
-Channel::GroupMemberChangeInfo Channel::groupSelfRemoveInfo() const
-{
-    if (mPriv->readiness != ReadinessClosed)
-        warning() << "Channel::groupSelfRemoveInfo() used with readiness" << mPriv->readiness << "!= ReadinessClosed";
-    else if (!mPriv->interfaces.contains(TELEPATHY_INTERFACE_CHANNEL_INTERFACE_GROUP))
-        warning() << "Channel::groupSelfRemoveInfo() used with no group interface";
-
-    return mPriv->groupSelfRemoveInfo;
-}
-
-ChannelInterface* Channel::baseInterface() const
-{
-    return mPriv->baseInterface;
-}
-
-void Channel::gotMainProperties(QDBusPendingCallWatcher* watcher)
-{
-    QDBusPendingReply<QVariantMap> reply = *watcher;
-    QVariantMap props;
-
-    if (!reply.isError()) {
-        debug() << "Got reply to Properties::GetAll(Channel)";
-        props = reply.value();
-    } else {
-        warning().nospace() << "Properties::GetAll(Channel) failed with " << reply.error().name() << ": " << reply.error().message();
-    }
-
-    mPriv->extract0177MainProps(props);
-    // Add extraction (and possible fallbacks) in similar functions, called from here
-
-    mPriv->continueIntrospection();
-}
-
-void Channel::gotChannelType(QDBusPendingCallWatcher* watcher)
-{
-    QDBusPendingReply<QString> reply = *watcher;
-
-    if (reply.isError()) {
-        warning().nospace() << "Channel::GetChannelType() failed with " << reply.error().name() << ": " << reply.error().message() << ", Channel officially dead";
-        if ((mPriv->readiness != ReadinessDead) && (mPriv->readiness != ReadinessClosed))
-            mPriv->changeReadiness(ReadinessDead);
-        return;
-    }
-
-    debug() << "Got reply to fallback Channel::GetChannelType()";
-    mPriv->channelType = reply.value();
-    mPriv->continueIntrospection();
-}
-
-void Channel::gotHandle(QDBusPendingCallWatcher* watcher)
-{
-    QDBusPendingReply<uint, uint> reply = *watcher;
-
-    if (reply.isError()) {
-        warning().nospace() << "Channel::GetHandle() failed with " << reply.error().name() << ": " << reply.error().message() << ", Channel officially dead";
-        if ((mPriv->readiness != ReadinessDead) && (mPriv->readiness != ReadinessClosed))
-            mPriv->changeReadiness(ReadinessDead);
-        return;
-    }
-
-    debug() << "Got reply to fallback Channel::GetHandle()";
-    mPriv->targetHandleType = reply.argumentAt<0>();
-    mPriv->targetHandle = reply.argumentAt<1>();
-    mPriv->continueIntrospection();
-}
-
-void Channel::gotInterfaces(QDBusPendingCallWatcher* watcher)
-{
-    QDBusPendingReply<QStringList> reply = *watcher;
-
-    if (reply.isError()) {
-        warning().nospace() << "Channel::GetInterfaces() failed with " << reply.error().name() << ": " << reply.error().message() << ", Channel officially dead";
-        if ((mPriv->readiness != ReadinessDead) && (mPriv->readiness != ReadinessClosed))
-            mPriv->changeReadiness(ReadinessDead);
-        return;
-    }
-
-    debug() << "Got reply to fallback Channel::GetInterfaces()";
-    mPriv->interfaces = reply.value();
-    mPriv->nowHaveInterfaces();
-    mPriv->continueIntrospection();
-}
-
-void Channel::onClosed()
-{
-    debug() << "Got Channel::Closed";
-
-    if (mPriv->readiness == ReadinessFull)
-        mPriv->changeReadiness(ReadinessClosed);
-    else if ((mPriv->readiness != ReadinessDead) && (mPriv->readiness != ReadinessClosed))
-        mPriv->changeReadiness(ReadinessDead);
-}
-
-void Channel::onConnectionReadinessChanged(uint readiness)
-{
-    if (readiness == Connection::ReadinessDead && mPriv->readiness != ReadinessDead) {
-        debug() << "Owning connection died leaving an orphan Channel, changing to ReadinessDead";
-        mPriv->changeReadiness(ReadinessDead);
-    }
-}
-
-void Channel::onConnectionDestroyed()
-{
-    debug() << "Owning connection destroyed, cutting off dangling pointer";
-    mPriv->connection = 0;
-    return onConnectionReadinessChanged(Connection::ReadinessDead);
-}
-
-void Channel::gotGroupProperties(QDBusPendingCallWatcher* watcher)
-{
-    QDBusPendingReply<QVariantMap> reply = *watcher;
-    QVariantMap props;
-
-    if (!reply.isError()) {
-        debug() << "Got reply to Properties::GetAll(Channel.Interface.Group)";
-        props = reply.value();
-    } else {
-        warning().nospace() << "Properties::GetAll(Channel.Interface.Group) failed with " << reply.error().name() << ": " << reply.error().message();
-    }
-
-    mPriv->extract0176GroupProps(props);
-    // Add extraction (and possible fallbacks) in similar functions, called from here
-
-    mPriv->continueIntrospection();
-}
-
-void Channel::gotGroupFlags(QDBusPendingCallWatcher* watcher)
-{
-    QDBusPendingReply<uint> reply = *watcher;
-
-    if (reply.isError()) {
-        warning().nospace() << "Channel.Interface.Group::GetGroupFlags() failed with " << reply.error().name() << ": " << reply.error().message();
-    } else {
-        debug() << "Got reply to fallback Channel.Interface.Group::GetGroupFlags()";
-        mPriv->groupFlags = reply.value();
-
-        if (mPriv->groupFlags & ChannelGroupFlagProperties) {
-            warning() << " Reply included ChannelGroupFlagProperties, even though properties specified in 0.17.7 didn't work! - unsetting";
-            mPriv->groupFlags &= ~ChannelGroupFlagProperties;
-        }
-    }
-
-    mPriv->continueIntrospection();
-}
-
-void Channel::gotAllMembers(QDBusPendingCallWatcher* watcher)
-{
-    QDBusPendingReply<UIntList, UIntList, UIntList> reply = *watcher;
-
-    if (reply.isError()) {
-        warning().nospace() << "Channel.Interface.Group::GetAllMembers() failed with " << reply.error().name() << ": " << reply.error().message();
-    } else {
-        debug() << "Got reply to fallback Channel.Interface.Group::GetAllMembers()";
-
-        mPriv->groupHaveMembers = true;
-        mPriv->groupMembers = QSet<uint>::fromList(reply.argumentAt<0>());
-        mPriv->groupRemotePending = QSet<uint>::fromList(reply.argumentAt<2>());
-
-        foreach (uint handle, QSet<uint>::fromList(reply.argumentAt<1>())) {
-            mPriv->groupLocalPending[handle] = GroupMemberChangeInfo();
-        }
-    }
-
-    mPriv->continueIntrospection();
-}
-
-void Channel::gotLocalPending(QDBusPendingCallWatcher* watcher)
-{
-    QDBusPendingReply<LocalPendingInfoList> reply = *watcher;
-
-    if (reply.isError()) {
-        warning().nospace() << "Channel.Interface.Group::GetLocalPendingMembersWithInfo() failed with " << reply.error().name() << ": " << reply.error().message();
-        warning() << " Falling back to what GetAllMembers returned with no extended info";
-    } else {
-        debug() << "Got reply to fallback Channel.Interface.Group::GetLocalPendingMembersWithInfo()";
-
-        foreach (LocalPendingInfo info, reply.value()) {
-            mPriv->groupLocalPending[info.toBeAdded] =
-                GroupMemberChangeInfo(info.actor, info.reason, info.message);
-        }
-    }
-
-    mPriv->continueIntrospection();
-}
-
-void Channel::gotSelfHandle(QDBusPendingCallWatcher* watcher)
-{
-    QDBusPendingReply<uint> reply = *watcher;
-
-    if (reply.isError()) {
-        warning().nospace() << "Channel.Interface.Group::GetSelfHandle() failed with " << reply.error().name() << ": " << reply.error().message();
-    } else {
-        debug() << "Got reply to fallback Channel.Interface.Group::GetSelfHandle()";
-        mPriv->groupSelfHandle = reply.value();
-    }
-
-    mPriv->continueIntrospection();
-}
-
-void Channel::onGroupFlagsChanged(uint added, uint removed)
-{
-    debug().nospace() << "Got Channel.Interface.Group::GroupFlagsChanged(" << hex << added << ", " << removed << ")";
-
-    added &= ~(mPriv->groupFlags);
-    removed &= mPriv->groupFlags;
-
-    debug().nospace() << "Arguments after filtering (" << hex << added << ", " << removed << ")";
-
-    mPriv->groupFlags |= added;
-    mPriv->groupFlags &= ~removed;
-
-    if (added || removed) {
-        debug() << "Emitting groupFlagsChanged with" << mPriv->groupFlags << "value" << added << "added" << removed << "removed";
-        emit groupFlagsChanged(mPriv->groupFlags, added, removed);
-    }
-}
-
-void Channel::onMembersChanged(const QString& message, const Telepathy::UIntList& added, const Telepathy::UIntList& removed, const Telepathy::UIntList& localPending, const Telepathy::UIntList& remotePending, uint actor, uint reason)
-{
-    debug() << "Got Channel.Interface.Group::MembersChanged with" << added.size() << "added," << removed.size() << "removed," << localPending.size() << "moved to LP," << remotePending.size() << "moved to RP," << actor << " being the actor," << reason << "the reason and" << message << "the message";
-
-    if (!mPriv->groupHaveMembers) {
-        debug() << "Still waiting for initial group members, so ignoring delta signal...";
-        return;
-    }
-
-    UIntList currentAdded;
-    UIntList currentRemoved;
-    UIntList localAdded;
-    UIntList localRemoved;
-    UIntList remoteAdded;
-    UIntList remoteRemoved;
-
-    foreach (uint handle, added) {
-        if (!mPriv->groupMembers.contains(handle)) {
-            debug() << " +++" << handle;
-            mPriv->groupMembers.insert(handle);
-            currentAdded.append(handle);
-        }
-    }
-
-    foreach (uint handle, localPending) {
-        GroupMemberChangeInfo info(actor, reason, message);
-
-        // Special-case renaming a local-pending contact, if the signal is
-        // spec-compliant. Keep the old extended info in this case.
-        if (reason == ChannelGroupChangeReasonRenamed
-                && added.size() == 0
-                && localPending.size() == 1
-                && remotePending.size() == 0
-                && removed.size() == 1
-                && mPriv->groupLocalPending.contains(removed[0])) {
-            debug() << " Special-case local pending rename" << removed[0] << " -> " << handle;
-            info = mPriv->groupLocalPending[removed[0]];
-        }
-
-        if (!mPriv->groupLocalPending.contains(handle)) {
-            debug() << " LP" << handle;
-            mPriv->groupLocalPending[handle] = info;
-            localAdded.append(handle);
-        }
-    }
-
-    foreach (uint handle, remotePending) {
-        if (!mPriv->groupRemotePending.contains(handle)) {
-            debug() << " RP" << handle;
-            mPriv->groupRemotePending.insert(handle);
-            remoteAdded.append(handle);
-        }
-    }
-
-    foreach (uint handle, removed) {
-        debug() << " ---" << handle;
-
-        if (mPriv->groupMembers.remove(handle))
-            currentRemoved.append(handle);
-
-        if (mPriv->groupLocalPending.remove(handle))
-            localRemoved.append(handle);
-
-        if (mPriv->groupRemotePending.remove(handle))
-            remoteRemoved.append(handle);
-
-        if (handle == mPriv->groupSelfHandle) {
-            debug() << " Self handle removed, saving info...";
-            mPriv->groupSelfRemoveInfo = GroupMemberChangeInfo(actor, reason, message);
-        }
-    }
-
-    if (currentAdded.size() || currentRemoved.size()) {
-        debug() << " Emitting groupMembersChanged with" << currentAdded.size() << "contacts added and" << currentRemoved.size() << "contacts removed";
-        emit groupMembersChanged(mPriv->groupMembers, currentAdded, currentRemoved, actor, reason, message);
-    }
-
-    if (localAdded.size() || localRemoved.size()) {
-        debug() << " Emitting groupLocalPendingChanged with" << localAdded.size() << "contacts added and" << localRemoved.size() << "contacts removed";
-        emit groupLocalPendingChanged(mPriv->groupLocalPending, localAdded, localRemoved, actor, reason, message);
-    }
-
-    if (remoteAdded.size() || remoteRemoved.size()) {
-        debug() << " Emitting groupRemotePendingChanged with" << remoteAdded.size() << "contacts added and" << remoteRemoved.size() << "contacts removed";
-        emit groupMembersChanged(mPriv->groupRemotePending, remoteAdded, remoteRemoved, actor, reason, message);
-    }
-}
-
-void Channel::onHandleOwnersChanged(const Telepathy::HandleOwnerMap& added, const Telepathy::UIntList& removed)
-{
-    debug() << "Got Channel.Interface.Group::HandleOwnersChanged with" << added.size() << "added," << removed.size() << "removed";
-
-    if (!mPriv->groupAreHandleOwnersAvailable) {
-        debug() << "Still waiting for initial handle owners, so ignoring delta signal...";
-        return;
-    }
-
-    UIntList emitAdded;
-    UIntList emitRemoved;
-
-    for (HandleOwnerMap::const_iterator i = added.begin();
-                                        i != added.end();
-                                        ++i) {
-        uint handle = i.key();
-        uint global = i.value();
-
-        if (!mPriv->groupHandleOwners.contains(handle)
-                || mPriv->groupHandleOwners[handle] != global) {
-            debug() << " +++/changed" << handle << "->" << global;
-            mPriv->groupHandleOwners[handle] = global;
-            emitAdded.append(handle);
-        }
-    }
-
-    foreach (uint handle, removed) {
-        if (mPriv->groupHandleOwners.contains(handle)) {
-            debug() << " ---" << handle;
-            mPriv->groupHandleOwners.remove(handle);
-            emitRemoved.append(handle);
-        }
-    }
-
-    if (emitAdded.size() || emitRemoved.size()) {
-        debug() << "Emitting groupHandleOwnersChanged with" << emitAdded.size() << "added" << emitRemoved.size() << "removed";
-        emit groupHandleOwnersChanged(mPriv->groupHandleOwners, emitAdded, emitRemoved);
-    }
-}
-
-void Channel::onSelfHandleChanged(uint newSelfHandle)
-{
-    debug().nospace() << "Got Channel.Interface.Group::SelfHandleChanged";
-
-    if (newSelfHandle != mPriv->groupSelfHandle) {
-        mPriv->groupSelfHandle = newSelfHandle;
-        debug() << " Emitting groupSelfHandleChanged with new self handle" << newSelfHandle;
-        emit groupSelfHandleChanged(newSelfHandle);
-    }
-}
-
-}
-}
diff --git a/TelepathyQt4/cli-channel.h b/TelepathyQt4/cli-channel.h
deleted file mode 100644
index 7bcb4b9..0000000
--- a/TelepathyQt4/cli-channel.h
+++ /dev/null
@@ -1,826 +0,0 @@
-/*
- * This file is part of TelepathyQt4
- *
- * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
- * Copyright (C) 2008 Nokia Corporation
- *
- * 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.
- *
- * 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.
- *
- * 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 St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#ifndef _TelepathyQt4_cli_channel_h_HEADER_GUARD_
-#define _TelepathyQt4_cli_channel_h_HEADER_GUARD_
-
-/**
- * \addtogroup clientsideproxies Client-side proxies
- *
- * Proxy objects representing remote service objects accessed via D-Bus.
- *
- * In addition to providing direct access to methods, signals and properties
- * exported by the remote objects, some of these proxies offer features like
- * automatic inspection of remote object capabilities, property tracking,
- * backwards compatibility helpers for older services and other utilities.
- */
-
-/**
- * \defgroup clientchannel Channel proxies
- * \ingroup clientsideproxies
- *
- * Proxy objects representing remote Telepathy Channels and their optional
- * interfaces.
- */
-
-#include <TelepathyQt4/_gen/cli-channel.h>
-
-#include <QSet>
-
-#include <QDBusPendingCallWatcher>
-
-namespace Telepathy {
-namespace Client {
-class Channel;
-}
-}
-
-#include <TelepathyQt4/Client/Connection>
-#include <TelepathyQt4/Client/DBus>
-#include <TelepathyQt4/Client/DBusProxy>
-#include <TelepathyQt4/Client/OptionalInterfaceFactory>
-
-namespace Telepathy
-{
-namespace Client
-{
-
-/**
- * \class Channel
- * \ingroup clientchannel
- * \headerfile TelepathyQt4/cli-channel.h <TelepathyQt4/Client/Channel>
- *
- * High-level proxy object for accessing remote %Telepathy %Channel objects.
- *
- * It adds the following features compared to using ChannelInterface directly:
- * <ul>
- *  <li>Life cycle tracking</li>
- *  <li>Getting the channel type, handle type, handle and interfaces automatically</li>
- *  <li>Shared optional interface proxy instances</li>
- * </ul>
- *
- * The remote object state accessor functions on this object (interfaces(),
- * channelType(), targetHandleType(), targetHandle()) don't make any DBus calls;
- * instead, they return values cached from a previous introspection run. The
- * introspection process populates their values in the most efficient way
- * possible based on what the service implements. However, their value is not
- * defined unless the object has readiness #ReadinessFull, as returned by
- * readiness() and indicated by emissions of the readinessChanged() signal.
- *
- * Additionally, the state of the Group interface on the remote object (if
- * present) will be cached in the introspection process, and also tracked for
- * any changes.
- *
- * Each Channel is owned by a Connection. If the Connection becomes dead (as
- * signaled by Connection::readinessChanged) or is deleted, the Channel object
- * will transition to ReadinessDead too.
- */
-class Channel : public StatefulDBusProxy, private OptionalInterfaceFactory
-{
-    Q_OBJECT
-    Q_ENUMS(Readiness)
-
-public:
-    /**
-     * Describes readiness of the Channel for usage. The readiness depends on
-     * the state of the remote object. In suitable states, an asynchronous
-     * introspection process is started, and the Channel becomes more ready when
-     * that process is completed.
-     */
-    enum Readiness {
-        /**
-         * The object has just been created and introspection is still in
-         * progress. No functionality dependent on introspection is available.
-         *
-         * The readiness can change to any other state except ReadinessClosed
-         * depending on the result of the initial state query to the remote
-         * object.
-         */
-        ReadinessJustCreated = 0,
-
-        /**
-         * The remote object is alive and all introspection has been completed.
-         * Most functionality is available.
-         *
-         * The readiness can change to ReadinessDead or ReadinessClosed.
-         */
-        ReadinessFull = 5,
-
-        /**
-         * The remote object has gone into a state where it can no longer be
-         * used in an unexpected way. No functionality is available.
-         *
-         * No further readiness changes are possible.
-         */
-        ReadinessDead = 10,
-
-        /**
-         * The remote object has been closed and so can no longer be used.
-         * No functionality is available.
-         *
-         * No further readiness changes are possible.
-         */
-        ReadinessClosed = 15,
-
-        _ReadinessInvalid = 0xffff
-    };
-
-    /**
-     * Creates a Channel associated with the given object on the same service as
-     * the given connection.
-     *
-     * \param connection  Connection owning this Channel, and specifying the
-     *                    service.
-     * \param objectPath  Path to the object on the service.
-     * \param parent      Passed to the parent class constructor.
-     */
-    Channel(Connection* connection,
-            const QString& objectPath,
-            QObject* parent = 0);
-
-    /**
-     * Class destructor.
-     */
-    ~Channel();
-
-    /**
-     * Returns the owning Connection of the Channel.
-     *
-     * \return Pointer to the Connection.
-     */
-    Connection* connection() const;
-
-    /**
-     * Returns the current readiness of the Channel.
-     *
-     * \return The readiness, as defined in #Readiness.
-     */
-    Readiness readiness() const;
-
-    /**
-     * Returns a list of optional interfaces implemented by the remote object.
-     *
-     * \return D-Bus names of the implemented optional interfaces.
-     */
-    QStringList interfaces() const;
-
-    /**
-     * Returns the type of this channel.
-     *
-     * \return D-Bus interface name for the type of the channel.
-     */
-    QString channelType() const;
-
-    /**
-     * Returns the type of the handle returned by #targetHandle().
-     *
-     * \return The type of the handle, as specified in #HandleType.
-     */
-    uint targetHandleType() const;
-
-    /**
-     * Returns the handle of the remote party with which this channel
-     * communicates.
-     *
-     * \return The handle, which is of the type #targetHandleType() indicates.
-     */
-    uint targetHandle() const;
-
-public Q_SLOTS:
-    /**
-     * Close the channel.
-     *
-     * When this method is used as a slot, it is fire-and-forget. If you want
-     * to know if an error occurs when closing the channel, then you should
-     * use the returned object.
-     *
-     * A channel can be closed if its Readiness is ReadinessJustCreated or
-     * ReadinessFull. It cannot be closed if its Readiness is ReadinessDead or
-     * ReadinessClosed. If this method is called on a channel which is already
-     * in either the ReadinessDead or ReadinessClosed state, a DBus error of type
-     * TELEPATHY_ERROR_NOT_AVAILABLE will be returned.
-     *
-     * If the introspection of a channel is not complete (ReadinessJustCreated)
-     * when close() is called, the channel readiness will change to ReadinessDead
-     * instead of ReadinessClosed, which results if the channel is closed after
-     * the introspection is complete (ReadinessFull).
-     *
-     * \return QDBusPendingReply object for the call to Close() on the Channel
-     *         interface.
-     */
-    QDBusPendingReply<> close();
-
-Q_SIGNALS:
-    /**
-     * Emitted whenever the readiness of the Channel changes. When the channel
-     * is closed, this signal will be emitted with readiness #ReadinessClosed.
-     *
-     * \param newReadiness The new readiness, as defined in #Readiness.
-     */
-    void readinessChanged(uint newReadiness);
-
-    /**
-     * \name Group interface
-     *
-     * Cached access to state of the group interface on the associated remote
-     * object, if the interface is present. All methods return undefined values
-     * if the list returned by interfaces() doesn't include
-     * #TELEPATHY_INTERFACE_CHANNEL_INTERFACE_GROUP or if the object doesn't have
-     * readiness #ReadinessFull.
-     *
-     * As the Group interface state can change freely during the lifetime of the
-     * group due to events like new contacts joining the group, the cached state
-     * is automatically kept in sync with the remote object's state by hooking
-     * to the change notification signals present in the D-Bus interface.
-     *
-     * As the cached value changes, change notification signals are emitted.
-     * However, the value being initially discovered by introspection is still
-     * signaled by a readiness change to #ReadinessFull.
-     *
-     * There is a change notification signal &lt;attribute&gt;Changed
-     * corresponding to each cached attribute. The first parameter for each of
-     * these signals is the new value of the attribute, which is suited for
-     * displaying the value of the attribute in a widget in a model-view
-     * fashion. The remaining arguments depend on the attribute, but in general
-     * include at least the delta from the previous state of the attribute to
-     * the new state.
-     *
-     * Check the individual signals' descriptions for details.
-     */
-    //@{
-
-public:
-
-    /**
-     * Returns a set of flags indicating the capabilities and behaviour of the
-     * group represented by the remote object.
-     *
-     * Change notification is via groupFlagsChanged().
-     *
-     * \return Bitfield combination of flags, as defined in #ChannelGroupFlag.
-     */
-    uint groupFlags() const;
-
-    /**
-     * Returns the current members of the group.
-     *
-     * \return Set of handles representing the members.
-     */
-    QSet<uint> groupMembers() const;
-
-    /**
-     * Class opaquely storing information on a group membership change for a
-     * single member.
-     *
-     * Extended information is not always available; this will be reflected by
-     * the return value of isValid().
-     */
-    class GroupMemberChangeInfo
-    {
-    public:
-
-        /**
-         * \internal
-         */
-        GroupMemberChangeInfo()
-            : mActor(-1), mReason(0), mIsValid(false) {}
-
-        /**
-         * \internal
-         */
-        GroupMemberChangeInfo(uint actor, uint reason, const QString& message)
-            : mActor(actor), mReason(reason), mMessage(message), mIsValid(true) {}
-
-        /**
-         * Returns whether or not this object actually contains valid
-         * information received from the service. If the returned value is
-         * false, the values returned by the other methods for this object are
-         * undefined.
-         *
-         * \return Whether the information stored in this object is valid.
-         */
-        bool isValid() const { return mIsValid; }
-
-        /**
-         * Returns the contact requesting or causing the change.
-         *
-         * \return The handle of the contact.
-         */
-        uint actor() const { return mActor; }
-
-        /**
-         * Returns the reason for the change.
-         *
-         * \return The reason, as specified in #ChannelGroupChangeReason.
-         */
-        uint reason() const { return mReason; }
-
-        /**
-         * Returns a human-readable message from the contact represented by
-         * actor() pertaining to the change, or an empty string if there is no
-         * message.
-         *
-         * \return The message as a string.
-         */
-        const QString& message() const { return mMessage; }
-
-    private:
-        uint mActor;
-        uint mReason;
-        QString mMessage;
-        bool mIsValid;
-    };
-
-    /**
-     * Mapping from contact handles to local pending contact information.
-     */
-    typedef QMap<uint, GroupMemberChangeInfo> GroupMemberChangeInfoMap;
-
-    /**
-     * Returns the contacts currently waiting for local approval to join the
-     * group.
-     *
-     * The returned value is a mapping from contact handles to
-     * GroupMemberChangeInfo objects. The key specifies a contact, with the
-     * value potentially including extendend information on the original request
-     * leading to the contact appearing in the local pending members.
-     *
-     * A info object as a value in the mapping, for which
-     * GroupMemberChangeInfo::isValid() returns <code>false</code> indicates a
-     * member for which no extended information has been received from the
-     * service. This will only happen for old services, for which neither the
-     * LocalPending property nor the GetLocalPendingMembersWithInfo method is
-     * usable.
-     *
-     * \returns A mapping from handles to info for the members waiting for local
-     *          approval.
-     */
-    GroupMemberChangeInfoMap groupLocalPending() const;
-
-    /**
-     * Returns the contacts currently waiting for remote approval to join the
-     * group.
-     *
-     * \returns Set of handles representing the contacts.
-     */
-    QSet<uint> groupRemotePending() const;
-
-    /**
-     * Returns whether globally valid handles can be looked up using the
-     * channel-specific handle on this channel using this object.
-     *
-     * Handle owner lookup is only available if:
-     * <ul>
-     *  <li>The object has readiness #ReadinessFull
-     *  <li>The list returned by interfaces() contains
-     *        #TELEPATHY_INTERFACE_CHANNEL_INTERFACE_GROUP</li>
-     *  <li>The set of flags returned by groupFlags() contains
-     *        GroupFlagProperties and GroupFlagChannelSpecificHandles</li>
-     * </ul>
-     *
-     * If this function returns <code>false</code>, the return value of
-     * groupHandleOwners() is undefined and groupHandleOwnersChanged() will
-     * never be emitted.
-     *
-     * The value returned by this function will stay fixed for the entire time
-     * the object spends having readiness #ReadinessFull, so no change
-     * notification is provided.
-     *
-     * \return If handle owner lookup functionality is available.
-     */
-    bool groupAreHandleOwnersAvailable() const;
-
-    /**
-     * Returns a mapping of handles specific to this channel to globally valid
-     * handles.
-     *
-     * The mapping includes at least all of the channel-specific handles in this
-     * channel's members, local-pending and remote-pending sets as keys. Any
-     * handle not in the keys of this mapping is not channel-specific in this
-     * channel. Handles which are channel-specific, but for which the owner is
-     * unknown, appear in this mapping with 0 as owner.
-     *
-     * \return A mapping from group-specific handles to globally valid handles.
-     */
-    HandleOwnerMap groupHandleOwners() const;
-
-    /**
-     * Returns whether the value returned by groupSelfHandle() is guaranteed to
-     * stay synchronized with what groupInterface()->GetSelfHandle() would
-     * return. Older services not providing group properties don't necessarily
-     * emit the SelfHandleChanged signal either, so self handle changes can't be
-     * reliably tracked.
-     *
-     * \return Whether or not changes to the self handle are tracked.
-     */
-    bool groupIsSelfHandleTracked() const;
-
-    /**
-     * Returns a handle representing the user in the group if the user is a
-     * member of the group, otherwise either a handle representing the user or
-     * 0.
-     *
-     * \return A contact handle representing the user, if possible.
-     */
-    uint groupSelfHandle() const;
-
-    /**
-     * Returns information on the removal of the local user from the group. If
-     * the user hasn't been removed from the group, an object for which
-     * GroupMemberChangeInfo::isValid() returns <code>false</code> is returned.
-     *
-     * This method only after the channel has gone into readiness
-     * #ReadinessClosed. This is useful for getting the
-     * remove information after missing the corresponding groupMembersChanged()
-     * (or groupLocalPendingChanged()/groupRemotePendingChanged()) signal, as
-     * the local user being removed usually causes the remote %Channel to be
-     * closed, and consequently the Channel object going into that readiness
-     * state.
-     *
-     * The returned information is not guaranteed to be correct if
-     * groupIsSelfHandleTracked() returns false and a self handle change has
-     * occurred on the remote object.
-     *
-     * \return The remove info in a GroupMemberChangeInfo object.
-     */
-    GroupMemberChangeInfo groupSelfRemoveInfo() const;
-
-Q_SIGNALS:
-
-    /**
-     * Emitted when the value returned by groupFlags() changes.
-     *
-     * \param flags The value which would now be returned by groupFlags().
-     * \param added Flags added compared to the previous value.
-     * \param removed Flags removed compared to the previous value.
-     */
-    void groupFlagsChanged(uint flags, uint added, uint removed);
-
-    /**
-     * Emitted when the value returned by groupMembers() changes.
-     *
-     * \param members The value which would now be returned by groupMembers().
-     * \param added Handles of the contacts which were added to the value.
-     * \param removed Handles of the contacts which were removed from the value.
-     * \param actor Handle of the contact requesting or causing the change.
-     * \param reason Reason of the change, as specified in
-     *        #ChannelGroupChangeReason.
-     * \param message Message specified by the actor related to the change, such
-     *        as the part message in IRC.
-     */
-    void groupMembersChanged(const QSet<uint>& members, const Telepathy::UIntList& added, const Telepathy::UIntList& removed, uint actor, uint reason, const QString& message);
-
-    /**
-     * Emitted when the value returned by groupLocalPending() changes.
-     *
-     * The added and remove lists only specify the handles of the contacts added
-     * to or removed from the mapping, not the extended information pertaining
-     * to them. Local pending info never changes for a particular contact after
-     * the contact first appears in the mapping, so no change notification is
-     * necessary for the extended information itself.
-     *
-     * \param localPending The value which would now be returned by
-     *        groupLocalPending().
-     * \param added Handles of the contacts which were added to the value.
-     * \param removed Handles of the contacts which were removed from the value.
-     * \param actor Handle of the contact requesting or causing the change.
-     * \param reason Reason of the change, as specified in
-     *        #ChannelGroupChangeReason.
-     * \param message Message specified by the actor related to the change, such
-     *        as the part message in IRC.
-     */
-    void groupLocalPendingChanged(const GroupMemberChangeInfoMap& localPending, const Telepathy::UIntList& added, const Telepathy::UIntList& removed, uint actor, uint reason, const QString& message);
-
-    /**
-     * Emitted when the value returned by groupRemotePending() changes.
-     *
-     * \param remotePending The value which would now be returned by
-     *        groupRemotePending().
-     * \param added Handles of the contacts which were added to the value.
-     * \param removed Handles of the contacts which were removed from the value.
-     * \param actor Handle of the contact requesting or causing the change.
-     * \param reason Reason of the change, as specified in
-     *        #ChannelGroupChangeReason.
-     * \param message Message specified by the actor related to the change, such
-     *        as the part message in IRC.
-     */
-    void groupRemotePendingChanged(const QSet<uint>& remotePending, const Telepathy::UIntList& added, const Telepathy::UIntList& removed, uint actor, uint reason, const QString& message);
-
-    /**
-     * Emitted when the value returned by groupHandleOwners() changes.
-     *
-     * \param owners The value which would now be returned by
-     *               groupHandleOwners().
-     * \param added Handles which have been added to the mapping as keys, or
-     *              existing handle keys for which the mapped-to value has changed.
-     * \param removed Handles which have been removed from the mapping.
-     */
-    void groupHandleOwnersChanged(const HandleOwnerMap& owners, const Telepathy::UIntList& added, const Telepathy::UIntList& removed);
-
-    /**
-     * Emitted when the value returned by groupSelfHandle() changes.
-     *
-     * \param selfHandle The value which would now be returned by
-     *                   groupSelfHandle().
-     */
-    void groupSelfHandleChanged(uint selfHandle);
-
-    /**
-     * \name Optional interface proxy factory
-     *
-     * Factory functions fabricating proxies for optional %Channel interfaces and
-     * interfaces for specific channel types.
-     */
-    //@{
-
-public:
-
-    /**
-     * Specifies if the interface being supported by the remote object should be
-     * checked by optionalInterface(), typeInterface() and the convenience
-     * functions for them.
-     */
-    enum InterfaceSupportedChecking
-    {
-        /**
-         * Don't return an interface instance unless it can be guaranteed that
-         * the remote object actually implements the interface.
-         */
-        CheckInterfaceSupported,
-
-        /**
-         * Return an interface instance even if it can't be verified that the
-         * remote object supports the interface.
-         */
-        BypassInterfaceCheck
-    };
-
-    /**
-     * Returns a pointer to a valid instance of a given %Channel optional
-     * interface class, associated with the same remote object the Channel is
-     * associated with, and destroyed together with the Channel.
-     *
-     * If the list returned by interfaces() doesn't contain the name of the
-     * interface requested <code>0</code> is returned. This check can be
-     * bypassed by specifying #BypassInterfaceCheck for <code>check</code>, in
-     * which case a valid instance is always returned.
-     *
-     * If the object doesn't have readiness #ReadinessFull, the list returned by
-     * interfaces() isn't guaranteed to yet represent the full set of interfaces
-     * supported by the remote object. Hence the check might fail even if the
-     * remote object actually supports the requested interface; using
-     * #BypassInterfaceCheck is suggested when the channel is not fully ready.
-     *
-     * \see OptionalInterfaceFactory::interface
-     *
-     * \tparam Interface Class of the optional interface to get.
-     * \param check Should an instance be returned even if it can't be
-     *              determined that the remote object supports the
-     *              requested interface.
-     * \return Pointer to an instance of the interface class, or <code>0</code>.
-     */
-    template <class Interface>
-    inline Interface* optionalInterface(InterfaceSupportedChecking check = CheckInterfaceSupported) const
-    {
-        // Check for the remote object supporting the interface
-        QString name(Interface::staticInterfaceName());
-        if (check == CheckInterfaceSupported && !interfaces().contains(name))
-            return 0;
-
-        // If present or forced, delegate to OptionalInterfaceFactory
-        return OptionalInterfaceFactory::interface<Interface>(*baseInterface());
-    }
-
-    /**
-     * Convenience function for getting a CallState interface proxy.
-     *
-     * \param check Passed to optionalInterface()
-     * \return <code>optionalInterface<ChannelInterfaceCallStateInterface>(check)</code>
-     */
-    inline ChannelInterfaceCallStateInterface* callStateInterface(InterfaceSupportedChecking check = CheckInterfaceSupported) const
-    {
-        return optionalInterface<ChannelInterfaceCallStateInterface>(check);
-    }
-
-    /**
-     * Convenience function for getting a ChatState interface proxy.
-     *
-     * \param check Passed to optionalInterface()
-     * \return <code>optionalInterface<ChannelInterfaceChatStateInterface>(check)</code>
-     */
-    inline ChannelInterfaceChatStateInterface* chatStateInterface(InterfaceSupportedChecking check = CheckInterfaceSupported) const
-    {
-        return optionalInterface<ChannelInterfaceChatStateInterface>(check);
-    }
-
-    /**
-     * Convenience function for getting a DTMF interface proxy.
-     *
-     * \param check Passed to optionalInterface()
-     * \return <code>optionalInterface<ChannelInterfaceDTMFInterface>(check)</code>
-     */
-    inline ChannelInterfaceDTMFInterface* DTMFInterface(InterfaceSupportedChecking check = CheckInterfaceSupported) const
-    {
-        return optionalInterface<ChannelInterfaceDTMFInterface>(check);
-    }
-
-    /**
-     * Convenience function for getting a Group interface proxy.
-     *
-     * \param check Passed to optionalInterface()
-     * \return <code>optionalInterface<ChannelInterfaceGroupInterface>(check)</code>
-     */
-    inline ChannelInterfaceGroupInterface* groupInterface(InterfaceSupportedChecking check = CheckInterfaceSupported) const
-    {
-        return optionalInterface<ChannelInterfaceGroupInterface>(check);
-    }
-
-    /**
-     * Convenience function for getting a Hold interface proxy.
-     *
-     * \param check Passed to optionalInterface()
-     * \return <code>optionalInterface<ChannelInterfaceHoldInterface>(check)</code>
-     */
-    inline ChannelInterfaceHoldInterface* holdInterface(InterfaceSupportedChecking check = CheckInterfaceSupported) const
-    {
-        return optionalInterface<ChannelInterfaceHoldInterface>(check);
-    }
-
-    /**
-     * Convenience function for getting a MediaSignalling interface proxy.
-     *
-     * \param check Passed to optionalInterface()
-     * \return <code>optionalInterface<ChannelInterfaceMediaSignallingInterface>(check)</code>
-     */
-    inline ChannelInterfaceMediaSignallingInterface* mediaSignallingInterface(InterfaceSupportedChecking check = CheckInterfaceSupported) const
-    {
-        return optionalInterface<ChannelInterfaceMediaSignallingInterface>(check);
-    }
-
-    /**
-     * Convenience function for getting a Password interface proxy.
-     *
-     * \param check Passed to optionalInterface()
-     * \return <code>optionalInterface<ChannelInterfacePasswordInterface>(check)</code>
-     */
-    inline ChannelInterfacePasswordInterface* passwordInterface(InterfaceSupportedChecking check = CheckInterfaceSupported) const
-    {
-        return optionalInterface<ChannelInterfacePasswordInterface>(check);
-    }
-
-    /**
-     * Convenience function for getting a Properties interface proxy. The
-     * Properties interface is not necessarily reported by the services, so a
-     * <code>check</code> parameter is not provided, and the interface is always
-     * assumed to be present.
-     *
-     * \return
-     * <code>optionalInterface<DBus::PropertiesInterface>(BypassInterfaceCheck)</code>
-     */
-    inline DBus::PropertiesInterface* propertiesInterface() const
-    {
-        return optionalInterface<DBus::PropertiesInterface>(BypassInterfaceCheck);
-    }
-
-    /**
-     * Returns a pointer to a valid instance of a given %Channel type interface
-     * class, associated with the same remote object the Channel is
-     * associated with, and destroyed together with the Channel.
-     *
-     * If the interface name returned by channelType() isn't equivalent to the
-     * name of the requested interface, or the Channel doesn't have readiness
-     * #ReadinessFull, <code>0</code> is returned. This check can be bypassed by
-     * specifying #BypassInterfaceCheck for <code>check</code>, in which case a
-     * valid instance is always returned.
-     *
-     * Convenience functions are provided for well-known channel types. However,
-     * there is no convenience getter for TypeContactList because the proxy for
-     * that interface doesn't actually have any functionality.
-     *
-     * \see OptionalInterfaceFactory::interface
-     *
-     * \tparam Interface Class of the optional interface to get.
-     * \param check Should an instance be returned even if it can't be
-     *              determined that the remote object is of the requested
-     *              channel type.
-     * \return Pointer to an instance of the interface class, or <code>0</code>.
-     */
-    template <class Interface>
-    inline Interface* typeInterface(InterfaceSupportedChecking check = CheckInterfaceSupported) const
-    {
-        // Check for the remote object having the correct channel type
-        QString name(Interface::staticInterfaceName());
-        if (check == CheckInterfaceSupported && channelType() != name)
-            return 0;
-
-        // If correct type or check bypassed, delegate to OIF
-        return OptionalInterfaceFactory::interface<Interface>(*baseInterface());
-    }
-
-    /**
-     * Convenience function for getting a TypeRoomList interface proxy.
-     *
-     * \param check Passed to typeInterface()
-     * \return <code>typeInterface<ChannelTypeRoomListInterface>(check)</code>
-     */
-    inline ChannelTypeRoomListInterface* roomListInterface(InterfaceSupportedChecking check = CheckInterfaceSupported) const
-    {
-        return typeInterface<ChannelTypeRoomListInterface>(check);
-    }
-
-    /**
-     * Convenience function for getting a TypeStreamedMedia interface proxy.
-     *
-     * \param check Passed to typeInterface()
-     * \return <code>typeInterface<ChannelTypeStreamedMediaInterface>(check)</code>
-     */
-    inline ChannelTypeStreamedMediaInterface* streamedMediaInterface(InterfaceSupportedChecking check = CheckInterfaceSupported) const
-    {
-        return typeInterface<ChannelTypeStreamedMediaInterface>(check);
-    }
-
-    /**
-     * Convenience function for getting a TypeText interface proxy.
-     *
-     * \param check Passed to typeInterface()
-     * \return <code>typeInterface<ChannelTypeTextInterface>(check)</code>
-     */
-    inline ChannelTypeTextInterface* textInterface(InterfaceSupportedChecking check = CheckInterfaceSupported) const
-    {
-        return typeInterface<ChannelTypeTextInterface>(check);
-    }
-
-    /**
-     * Convenience function for getting a TypeTubes interface proxy.
-     *
-     * \param check Passed to typeInterface()
-     * \return <code>typeInterface<ChannelTypeTubesInterface>(check)</code>
-     */
-    inline ChannelTypeTubesInterface* tubesInterface(InterfaceSupportedChecking check = CheckInterfaceSupported) const
-    {
-        return typeInterface<ChannelTypeTubesInterface>(check);
-    }
-
-protected:
-    /**
-     * Get the ChannelInterface for this Channel class. This method is
-     * protected since the convenience methods provided by this class should
-     * always be used instead of the interface by users of the class.
-     *
-     * \return A pointer to the existing ChannelInterface for this Channel
-     */
-    ChannelInterface* baseInterface() const;
-
-    //@}
-
-private Q_SLOTS:
-    void gotMainProperties(QDBusPendingCallWatcher* watcher);
-    void gotChannelType(QDBusPendingCallWatcher* watcher);
-    void gotHandle(QDBusPendingCallWatcher* watcher);
-    void gotInterfaces(QDBusPendingCallWatcher* watcher);
-    void onClosed();
-
-    void onConnectionReadinessChanged(uint readiness);
-    void onConnectionDestroyed();
-
-    void gotGroupProperties(QDBusPendingCallWatcher* watcher);
-    void gotGroupFlags(QDBusPendingCallWatcher* watcher);
-    void gotAllMembers(QDBusPendingCallWatcher* watcher);
-    void gotLocalPending(QDBusPendingCallWatcher* watcher);
-    void gotSelfHandle(QDBusPendingCallWatcher* watcher);
-    void onGroupFlagsChanged(uint, uint);
-    void onMembersChanged(const QString&, const Telepathy::UIntList&, const Telepathy::UIntList&, const Telepathy::UIntList&, const Telepathy::UIntList&, uint, uint);
-    void onHandleOwnersChanged(const Telepathy::HandleOwnerMap&, const Telepathy::UIntList&);
-    void onSelfHandleChanged(uint);
-
-private:
-    struct Private;
-    friend struct Private;
-    Private *mPriv;
-};
-
-}
-}
-
-Q_DECLARE_METATYPE(Telepathy::Client::Channel::GroupMemberChangeInfo);
-Q_DECLARE_METATYPE(Telepathy::Client::Channel::GroupMemberChangeInfoMap);
-
-#endif
diff --git a/TelepathyQt4/cli-connection-manager.cpp b/TelepathyQt4/cli-connection-manager.cpp
deleted file mode 100644
index 3c95d62..0000000
--- a/TelepathyQt4/cli-connection-manager.cpp
+++ /dev/null
@@ -1,460 +0,0 @@
-/*
- * This file is part of TelepathyQt4
- *
- * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
- * Copyright (C) 2008 Nokia Corporation
- *
- * 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.
- *
- * 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.
- *
- * 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 St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#include "cli-connection-manager.h"
-
-#include <QtCore/QQueue>
-#include <QtCore/QStringList>
-#include <QtCore/QTimer>
-
-#include <TelepathyQt4/Client/DBus>
-#include <TelepathyQt4/ManagerFile>
-#include <TelepathyQt4/Types>
-
-#include "TelepathyQt4/debug-internal.hpp"
-
-namespace Telepathy
-{
-namespace Client
-{
-
-ProtocolParameter::ProtocolParameter(const QString &name,
-                                     const QDBusSignature &dbusSignature,
-                                     QVariant defaultValue,
-                                     Telepathy::ConnMgrParamFlag flags)
-    : mName(name),
-      mDBusSignature(dbusSignature),
-      mType(ManagerFile::variantFromDBusSignature("", dbusSignature.signature())),
-      mDefaultValue(defaultValue),
-      mFlags(flags)
-{
-}
-
-
-ProtocolParameter::~ProtocolParameter()
-{
-}
-
-
-bool ProtocolParameter::isRequired() const
-{
-    return mFlags & ConnMgrParamFlagRequired;
-}
-
-
-bool ProtocolParameter::isSecret() const
-{
-    return mFlags & ConnMgrParamFlagSecret;
-}
-
-
-bool ProtocolParameter::requiredForRegistration() const
-{
-    return mFlags & ConnMgrParamFlagRegister;
-}
-
-
-bool ProtocolParameter::operator==(const ProtocolParameter &other) const
-{
-    return (mName == other.name());
-}
-
-
-bool ProtocolParameter::operator==(const QString &name) const
-{
-    return (mName == name);
-}
-
-
-struct ProtocolInfo::Private
-{
-    ProtocolParameterList params;
-};
-
-
-ProtocolInfo::ProtocolInfo(const QString &cmName, const QString &name)
-    : mPriv(new Private()),
-      mCmName(cmName),
-      mName(name)
-{
-}
-
-
-ProtocolInfo::~ProtocolInfo()
-{
-    Q_FOREACH (ProtocolParameter *param, mPriv->params) {
-        delete param;
-    }
-}
-
-
-const ProtocolParameterList &ProtocolInfo::parameters() const
-{
-    return mPriv->params;
-}
-
-
-bool ProtocolInfo::hasParameter(const QString &name) const
-{
-    Q_FOREACH (ProtocolParameter *param, mPriv->params) {
-        if (param->name() == name) {
-            return true;
-        }
-    }
-    return false;
-}
-
-
-bool ProtocolInfo::canRegister() const
-{
-    return hasParameter(QLatin1String("register"));
-}
-
-
-void ProtocolInfo::addParameter(const ParamSpec &spec)
-{
-    QVariant defaultValue;
-    if (spec.flags & ConnMgrParamFlagHasDefault)
-        defaultValue = spec.defaultValue.variant();
-
-    uint flags = spec.flags;
-    if (spec.name.endsWith("password"))
-        flags |= Telepathy::ConnMgrParamFlagSecret;
-
-    ProtocolParameter *param = new ProtocolParameter(spec.name,
-            QDBusSignature(spec.signature),
-            defaultValue,
-            (Telepathy::ConnMgrParamFlag) flags);
-
-    mPriv->params.append(param);
-}
-
-
-struct ConnectionManager::Private
-{
-    ConnectionManager *parent;
-    ConnectionManagerInterface* baseInterface;
-    bool ready;
-    QQueue<void (Private::*)()> introspectQueue;
-    QQueue<QString> getParametersQueue;
-    QQueue<QString> protocolQueue;
-    QStringList interfaces;
-    ProtocolInfoList protocols;;
-
-    Private(ConnectionManager *parent);
-    ~Private();
-
-    static QString makeBusName(const QString& name);
-    static QString makeObjectPath(const QString& name);
-
-    ProtocolInfo *protocol(const QString &protocolName);
-
-    bool checkConfigFile();
-    void callReadConfig();
-    void callGetAll();
-    void callGetParameters();
-    void callListProtocols();
-};
-
-
-ConnectionManager::Private::Private(ConnectionManager *parent)
-    : parent(parent),
-      baseInterface(new ConnectionManagerInterface(parent->dbusConnection(),
-                    parent->busName(), parent->objectPath(), parent)),
-      ready(false)
-{
-    debug() << "Creating new ConnectionManager:" << parent->busName();
-
-    introspectQueue.enqueue(&Private::callReadConfig);
-    QTimer::singleShot(0, parent, SLOT(continueIntrospection()));
-}
-
-
-ConnectionManager::Private::~Private()
-{
-    Q_FOREACH (ProtocolInfo* info, protocols) {
-        delete info;
-    }
-}
-
-
-QString ConnectionManager::Private::makeBusName(const QString& name)
-{
-    return QString::fromAscii(
-            TELEPATHY_CONNECTION_MANAGER_BUS_NAME_BASE).append(name);
-}
-
-
-QString ConnectionManager::Private::makeObjectPath(const QString& name)
-{
-    return QString::fromAscii(
-            TELEPATHY_CONNECTION_MANAGER_OBJECT_PATH_BASE).append(name);
-}
-
-
-ProtocolInfo *ConnectionManager::Private::protocol(const QString &protocolName)
-{
-    Q_FOREACH (ProtocolInfo *info, protocols) {
-        if (info->name() == protocolName) {
-            return info;
-        }
-    }
-    return NULL;
-}
-
-
-bool ConnectionManager::Private::checkConfigFile()
-{
-    ManagerFile f(parent->name());
-    if (!f.isValid()) {
-        return false;
-    }
-
-    Q_FOREACH (QString protocol, f.protocols()) {
-        ProtocolInfo *info = new ProtocolInfo(parent->name(),
-                                              protocol);
-        protocols.append(info);
-
-        Q_FOREACH (ParamSpec spec, f.parameters(protocol)) {
-            info->addParameter(spec);
-        }
-    }
-
-#if 0
-    Q_FOREACH (ProtocolInfo *info, protocols) {
-        qDebug() << "protocol name   :" << info->name();
-        qDebug() << "protocol cn name:" << info->cmName();
-        Q_FOREACH (ProtocolParameter *param, info->parameters()) {
-            qDebug() << "\tparam name:       " << param->name();
-            qDebug() << "\tparam is required:" << param->isRequired();
-            qDebug() << "\tparam is secret:  " << param->isSecret();
-            qDebug() << "\tparam value:      " << param->defaultValue();
-        }
-    }
-#endif
-
-    return true;
-}
-
-
-void ConnectionManager::Private::callReadConfig()
-{
-    if (!checkConfigFile()) {
-        introspectQueue.enqueue(&Private::callGetAll);
-        introspectQueue.enqueue(&Private::callListProtocols);
-    }
-
-    parent->continueIntrospection();
-}
-
-
-void ConnectionManager::Private::callGetAll()
-{
-    debug() << "Calling Properties::GetAll(ConnectionManager)";
-    QDBusPendingCallWatcher* watcher = new QDBusPendingCallWatcher(
-            parent->propertiesInterface()->GetAll(
-                TELEPATHY_INTERFACE_CONNECTION_MANAGER), parent);
-    parent->connect(watcher,
-            SIGNAL(finished(QDBusPendingCallWatcher*)),
-            SLOT(onGetAllConnectionManagerReturn(QDBusPendingCallWatcher*)));
-}
-
-
-void ConnectionManager::Private::callGetParameters()
-{
-    QString protocol = getParametersQueue.dequeue();
-    protocolQueue.enqueue(protocol);
-    debug() << "Calling ConnectionManager::GetParameters(" <<
-        protocol << ")";
-    QDBusPendingCallWatcher* watcher = new QDBusPendingCallWatcher(
-            baseInterface->GetParameters(protocol), parent);
-    parent->connect(watcher,
-            SIGNAL(finished(QDBusPendingCallWatcher*)),
-            SLOT(onGetParametersReturn(QDBusPendingCallWatcher*)));
-}
-
-
-void ConnectionManager::Private::callListProtocols()
-{
-    debug() << "Calling ConnectionManager::ListProtocols";
-    QDBusPendingCallWatcher* watcher = new QDBusPendingCallWatcher(
-            baseInterface->ListProtocols(), parent);
-    parent->connect(watcher,
-            SIGNAL(finished(QDBusPendingCallWatcher*)),
-            SLOT(onListProtocolsReturn(QDBusPendingCallWatcher*)));
-}
-
-
-ConnectionManager::ConnectionManager(const QString& name, QObject* parent)
-    : StatelessDBusProxy(QDBusConnection::sessionBus(),
-            Private::makeBusName(name), Private::makeObjectPath(name),
-            parent),
-      mPriv(new Private(this)),
-      mName(name)
-{
-}
-
-
-ConnectionManager::ConnectionManager(const QDBusConnection& bus,
-        const QString& name, QObject* parent)
-    : StatelessDBusProxy(bus, Private::makeBusName(name),
-            Private::makeObjectPath(name), parent),
-      mPriv(new Private(this)),
-      mName(name)
-{
-}
-
-
-ConnectionManager::~ConnectionManager()
-{
-    delete mPriv;
-}
-
-
-QStringList ConnectionManager::interfaces() const
-{
-    return mPriv->interfaces;
-}
-
-
-QStringList ConnectionManager::supportedProtocols() const
-{
-    QStringList protocols;
-    Q_FOREACH (const ProtocolInfo *info, mPriv->protocols) {
-        protocols.append(info->name());
-    }
-    return protocols;
-}
-
-
-const ProtocolInfoList &ConnectionManager::protocols() const
-{
-    return mPriv->protocols;
-}
-
-
-bool ConnectionManager::isReady() const
-{
-    return mPriv->ready;
-}
-
-
-ConnectionManagerInterface* ConnectionManager::baseInterface() const
-{
-    return mPriv->baseInterface;
-}
-
-
-void ConnectionManager::onGetAllConnectionManagerReturn(
-        QDBusPendingCallWatcher* watcher)
-{
-    QDBusPendingReply<QVariantMap> reply = *watcher;
-    QVariantMap props;
-
-    if (!reply.isError()) {
-        debug() << "Got reply to Properties.GetAll(ConnectionManager)";
-        props = reply.value();
-    } else {
-        warning().nospace() <<
-            "Properties.GetAll(ConnectionManager) failed: " <<
-            reply.error().name() << ": " << reply.error().message();
-    }
-
-    // If Interfaces is not supported, the spec says to assume it's
-    // empty, so keep the empty list mPriv was initialized with
-    if (props.contains("Interfaces")) {
-        mPriv->interfaces = qdbus_cast<QStringList>(props["Interfaces"]);
-    }
-    continueIntrospection();
-}
-
-
-void ConnectionManager::onListProtocolsReturn(
-        QDBusPendingCallWatcher* watcher)
-{
-    QDBusPendingReply<QStringList> reply = *watcher;
-    QStringList protocols;
-
-    if (!reply.isError()) {
-        debug() << "Got reply to ConnectionManager.ListProtocols";
-        protocols = reply.value();
-    } else {
-        warning().nospace() <<
-            "ConnectionManager.ListProtocols failed: " <<
-            reply.error().name() << ": " << reply.error().message();
-    }
-
-    Q_FOREACH (const QString &protocolName, protocols) {
-        mPriv->protocols.append(new ProtocolInfo(mName,
-                                                 protocolName));
-
-        mPriv->getParametersQueue.enqueue(protocolName);
-        mPriv->introspectQueue.enqueue(&Private::callGetParameters);
-    }
-    continueIntrospection();
-}
-
-
-void ConnectionManager::onGetParametersReturn(
-        QDBusPendingCallWatcher* watcher)
-{
-    QDBusPendingReply<ParamSpecList> reply = *watcher;
-    ParamSpecList parameters;
-    QString protocolName = mPriv->protocolQueue.dequeue();
-    ProtocolInfo *info = mPriv->protocol(protocolName);
-
-    if (!reply.isError()) {
-        debug() << "Got reply to ConnectionManager.GetParameters";
-        parameters = reply.value();
-    } else {
-        warning().nospace() <<
-            "ConnectionManager.GetParameters failed: " <<
-            reply.error().name() << ": " << reply.error().message();
-    }
-
-    Q_FOREACH (const ParamSpec& spec, parameters) {
-        debug() << "Parameter" << spec.name << "has flags" << spec.flags
-            << "and signature" << spec.signature;
-
-        info->addParameter(spec);
-    }
-    continueIntrospection();
-}
-
-void ConnectionManager::continueIntrospection()
-{
-    if (!mPriv->ready) {
-        if (mPriv->introspectQueue.isEmpty()) {
-            debug() << "ConnectionManager is ready";
-            mPriv->ready = true;
-            Q_EMIT ready(this);
-        } else {
-            (mPriv->*(mPriv->introspectQueue.dequeue()))();
-        }
-    }
-}
-
-} // Telepathy::Client
-} // Telepathy
-
-#include <TelepathyQt4/_gen/cli-connection-manager-body.hpp>
-#include <TelepathyQt4/_gen/cli-connection-manager.moc.hpp>
-#include <TelepathyQt4/cli-connection-manager.moc.hpp>
diff --git a/TelepathyQt4/cli-connection-manager.h b/TelepathyQt4/cli-connection-manager.h
deleted file mode 100644
index 0456a97..0000000
--- a/TelepathyQt4/cli-connection-manager.h
+++ /dev/null
@@ -1,234 +0,0 @@
-/*
- * This file is part of TelepathyQt4
- *
- * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
- * Copyright (C) 2008 Nokia Corporation
- *
- * 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.
- *
- * 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.
- *
- * 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 St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#ifndef _TelepathyQt4_cli_connection_manager_h_HEADER_GUARD_
-#define _TelepathyQt4_cli_connection_manager_h_HEADER_GUARD_
-
-/**
- * \addtogroup clientsideproxies Client-side proxies
- *
- * Proxy objects representing remote service objects accessed via D-Bus.
- *
- * In addition to providing direct access to methods, signals and properties
- * exported by the remote objects, some of these proxies offer features like
- * automatic inspection of remote object capabilities, property tracking,
- * backwards compatibility helpers for older services and other utilities.
- */
-
-/**
- * \defgroup clientcm Connection manager proxies
- * \ingroup clientsideproxies
- *
- * Proxy objects representing remote Telepathy ConnectionManager objects.
- */
-
-#include <TelepathyQt4/_gen/cli-connection-manager.h>
-
-#include <TelepathyQt4/Constants>
-#include <TelepathyQt4/Client/DBus>
-#include <TelepathyQt4/Client/DBusProxy>
-#include <TelepathyQt4/Client/OptionalInterfaceFactory>
-
-namespace Telepathy
-{
-namespace Client
-{
-
-class ProtocolParameter;
-class ProtocolInfo;
-
-typedef QList<ProtocolParameter*> ProtocolParameterList;
-typedef QList<ProtocolInfo*> ProtocolInfoList;
-
-class ProtocolParameter
-{
-public:
-    ProtocolParameter(const QString &name,
-                      const QDBusSignature &dbusSignature,
-                      QVariant defaultValue,
-                      Telepathy::ConnMgrParamFlag flags);
-    ~ProtocolParameter();
-
-    QString name() const { return mName; }
-    QDBusSignature dbusSignature() const { return mDBusSignature; }
-    QVariant type() const { return mType; }
-    QVariant defaultValue() const { return mDefaultValue; }
-
-    bool isRequired() const;
-    bool isSecret() const;
-    bool requiredForRegistration() const;
-
-    bool operator==(const ProtocolParameter &other) const;
-    bool operator==(const QString &name) const;
-
-private:
-    Q_DISABLE_COPY(ProtocolParameter);
-
-    QString mName;
-    QDBusSignature mDBusSignature;
-    QVariant mType;
-    QVariant mDefaultValue;
-    Telepathy::ConnMgrParamFlag mFlags;
-};
-
-
-class ProtocolInfo
-{
-public:
-    ~ProtocolInfo();
-
-    /**
-     * Get the short name of the connection manager (e.g. "gabble").
-     *
-     * \return The name of the connection manager
-     */
-    QString cmName() const { return mCmName; }
-
-    /**
-     * Get the untranslated name of the protocol as described in the Telepathy
-     * D-Bus API Specification (e.g. "jabber").
-     */
-    QString name() const { return mName; }
-
-    /**
-     * Return all supported parameters. The parameters' names
-     * may either be the well-known strings specified by the Telepathy D-Bus
-     * API Specification (e.g. "account" and "password"), or
-     * implementation-specific strings.
-     *
-     * \return A list of parameters
-     */
-    const ProtocolParameterList &parameters() const;
-
-    /**
-     * Return whether a given parameter can be passed to the connection
-     * manager when creating a connection to this protocol.
-     *
-     * \param name The name of a parameter
-     * \return true if the given parameter exists
-     */
-    bool hasParameter(const QString &name) const;
-
-    /**
-     * Return whether it might be possible to register new accounts on this
-     * protocol via Telepathy, by setting the special parameter named
-     * <code>register</code> to <code>true</code>.
-     *
-     * \return The same thing as hasParameter("register")
-     */
-    bool canRegister() const;
-
-private:
-    Q_DISABLE_COPY(ProtocolInfo);
-
-    ProtocolInfo(const QString &cmName, const QString &name);
-
-    void addParameter(const ParamSpec &spec);
-
-    struct Private;
-    friend struct Private;
-    friend class ConnectionManager;
-    Private *mPriv;
-    QString mCmName;
-    QString mName;
-};
-
-
-/**
- * \class ConnectionManager
- * \ingroup clientcm
- * \headerfile TelepathyQt4/cli-connection-manager.h <TelepathyQt4/Client/ConnectionManager>
- *
- * Object representing a Telepathy connection manager. Connection managers
- * allow connections to be made on one or more protocols.
- *
- * Most client applications should use this functionality via the
- * %AccountManager, to allow connections to be shared between client
- * applications.
- */
-class ConnectionManager : public StatelessDBusProxy,
-        private OptionalInterfaceFactory
-{
-    Q_OBJECT
-
-public:
-    ConnectionManager(const QString& name, QObject* parent = 0);
-    ConnectionManager(const QDBusConnection& bus,
-            const QString& name, QObject* parent = 0);
-
-    virtual ~ConnectionManager();
-
-    QString name() const { return mName; }
-
-    QStringList interfaces() const;
-
-    QStringList supportedProtocols() const;
-
-    const ProtocolInfoList &protocols() const;
-
-    /**
-     * Convenience function for getting a Properties interface proxy. The
-     * Properties interface is not necessarily reported by the services, so a
-     * <code>check</code> parameter is not provided, and the interface is
-     * always assumed to be present.
-     */
-    inline DBus::PropertiesInterface* propertiesInterface() const
-    {
-        return OptionalInterfaceFactory::interface<DBus::PropertiesInterface>(
-                *baseInterface());
-    }
-
-    bool isReady() const;
-
-Q_SIGNALS:
-    void ready(ConnectionManager*);
-
-protected:
-    /**
-     * Get the ConnectionManagerInterface for this ConnectionManager. This
-     * method is protected since the convenience methods provided by this
-     * class should generally be used instead of calling D-Bus methods
-     * directly.
-     *
-     * \return A pointer to the existing ConnectionManagerInterface for this
-     *         ConnectionManager
-     */
-    ConnectionManagerInterface* baseInterface() const;
-
-private Q_SLOTS:
-    void onGetParametersReturn(QDBusPendingCallWatcher*);
-    void onListProtocolsReturn(QDBusPendingCallWatcher*);
-    void onGetAllConnectionManagerReturn(QDBusPendingCallWatcher*);
-    void continueIntrospection();
-
-private:
-    Q_DISABLE_COPY(ConnectionManager);
-
-    struct Private;
-    friend struct Private;
-    Private *mPriv;
-    QString mName;
-};
-
-}
-}
-
-#endif
diff --git a/TelepathyQt4/cli-connection.cpp b/TelepathyQt4/cli-connection.cpp
deleted file mode 100644
index 759dc49..0000000
--- a/TelepathyQt4/cli-connection.cpp
+++ /dev/null
@@ -1,502 +0,0 @@
-/*
- * This file is part of TelepathyQt4
- *
- * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
- * Copyright (C) 2008 Nokia Corporation
- *
- * 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.
- *
- * 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.
- *
- * 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 St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#include "cli-connection.h"
-
-#include <TelepathyQt4/_gen/cli-connection-body.hpp>
-#include <TelepathyQt4/_gen/cli-connection.moc.hpp>
-#include <TelepathyQt4/cli-connection.moc.hpp>
-
-#include <QMap>
-#include <QQueue>
-#include <QString>
-#include <QtGlobal>
-
-#include <TelepathyQt4/Client/PendingVoidMethodCall>
-
-#include "debug-internal.hpp"
-
-namespace Telepathy
-{
-namespace Client
-{
-
-struct Connection::Private
-{
-    // Public object
-    Connection& parent;
-
-    // Instance of generated interface class
-    ConnectionInterface* baseInterface;
-
-    // Optional interface proxies
-    ConnectionInterfaceAliasingInterface* aliasing;
-    ConnectionInterfacePresenceInterface* presence;
-    DBus::PropertiesInterface* properties;
-
-    // Introspection
-    bool initialIntrospection;
-    Readiness readiness;
-    QStringList interfaces;
-    QQueue<void (Private::*)()> introspectQueue;
-
-    // Introspected properties
-    uint status;
-    uint statusReason;
-    uint aliasFlags;
-    StatusSpecMap presenceStatuses;
-    SimpleStatusSpecMap simplePresenceStatuses;
-
-    Private(Connection &parent)
-        : parent(parent)
-    {
-        aliasing = 0;
-        presence = 0;
-        properties = 0;
-        baseInterface = 0;
-
-        initialIntrospection = false;
-        readiness = ReadinessJustCreated;
-        status = ConnectionStatusDisconnected;
-        statusReason = ConnectionStatusReasonNoneSpecified;
-        aliasFlags = 0;
-    }
-
-    void startIntrospection()
-    {
-        Q_ASSERT(baseInterface == 0);
-        baseInterface = new ConnectionInterface(parent.dbusConnection(),
-            parent.busName(), parent.objectPath(), &parent);
-
-        debug() << "Connecting to StatusChanged()";
-
-        parent.connect(baseInterface,
-                       SIGNAL(StatusChanged(uint, uint)),
-                       SLOT(onStatusChanged(uint, uint)));
-
-        debug() << "Calling GetStatus()";
-
-        QDBusPendingCallWatcher* watcher =
-            new QDBusPendingCallWatcher(baseInterface->GetStatus(), &parent);
-        parent.connect(watcher,
-                       SIGNAL(finished(QDBusPendingCallWatcher*)),
-                       SLOT(gotStatus(QDBusPendingCallWatcher*)));
-    }
-
-    void introspectAliasing()
-    {
-        // The Aliasing interface is not usable before the connection is established
-        if (initialIntrospection) {
-            continueIntrospection();
-            return;
-        }
-
-        if (!aliasing) {
-            aliasing = parent.aliasingInterface();
-            Q_ASSERT(aliasing != 0);
-        }
-
-        debug() << "Calling GetAliasFlags()";
-        QDBusPendingCallWatcher* watcher =
-            new QDBusPendingCallWatcher(aliasing->GetAliasFlags(), &parent);
-        parent.connect(watcher,
-                       SIGNAL(finished(QDBusPendingCallWatcher*)),
-                       SLOT(gotAliasFlags(QDBusPendingCallWatcher*)));
-    }
-
-    void introspectMain()
-    {
-        // Introspecting the main interface is currently just calling
-        // GetInterfaces(), but it might include other stuff in the future if we
-        // gain GetAll-able properties on the connection
-        debug() << "Calling GetInterfaces()";
-        QDBusPendingCallWatcher* watcher =
-            new QDBusPendingCallWatcher(baseInterface->GetInterfaces(), &parent);
-        parent.connect(watcher,
-                       SIGNAL(finished(QDBusPendingCallWatcher*)),
-                       SLOT(gotInterfaces(QDBusPendingCallWatcher*)));
-    }
-
-    void introspectPresence()
-    {
-        // The Presence interface is not usable before the connection is established
-        if (initialIntrospection) {
-            continueIntrospection();
-            return;
-        }
-
-        if (!presence) {
-            presence = parent.presenceInterface();
-            Q_ASSERT(presence != 0);
-        }
-
-        debug() << "Calling GetStatuses() (legacy)";
-        QDBusPendingCallWatcher* watcher =
-            new QDBusPendingCallWatcher(presence->GetStatuses(), &parent);
-        parent.connect(watcher,
-                       SIGNAL(finished(QDBusPendingCallWatcher*)),
-                       SLOT(gotStatuses(QDBusPendingCallWatcher*)));
-    }
-
-    void introspectSimplePresence()
-    {
-        if (!properties) {
-            properties = parent.propertiesInterface();
-            Q_ASSERT(properties != 0);
-        }
-
-        debug() << "Getting available SimplePresence statuses";
-        QDBusPendingCall call =
-            properties->Get(TELEPATHY_INTERFACE_CONNECTION_INTERFACE_SIMPLE_PRESENCE,
-                           "Statuses");
-        QDBusPendingCallWatcher* watcher =
-            new QDBusPendingCallWatcher(call, &parent);
-        parent.connect(watcher,
-                       SIGNAL(finished(QDBusPendingCallWatcher*)),
-                       SLOT(gotSimpleStatuses(QDBusPendingCallWatcher*)));
-    }
-
-    void continueIntrospection()
-    {
-        if (introspectQueue.isEmpty()) {
-            if (initialIntrospection) {
-                initialIntrospection = false;
-                if (readiness < ReadinessNotYetConnected)
-                    changeReadiness(ReadinessNotYetConnected);
-            } else {
-                if (readiness != ReadinessDead)
-                    changeReadiness(ReadinessFull);
-            }
-        } else {
-            (this->*introspectQueue.dequeue())();
-        }
-    }
-
-    void changeReadiness(Readiness newReadiness)
-    {
-        Q_ASSERT(newReadiness != readiness);
-
-        switch (readiness) {
-            case ReadinessJustCreated:
-                break;
-            case ReadinessNotYetConnected:
-                Q_ASSERT(newReadiness == ReadinessConnecting
-                        || newReadiness == ReadinessDead);
-                break;
-            case ReadinessConnecting:
-                Q_ASSERT(newReadiness == ReadinessFull
-                        || newReadiness == ReadinessDead);
-                break;
-            case ReadinessFull:
-                Q_ASSERT(newReadiness == ReadinessDead);
-                break;
-            case ReadinessDead:
-            default:
-                Q_ASSERT(false);
-        }
-
-        debug() << "Readiness changed from" << readiness << "to" << newReadiness;
-        readiness = newReadiness;
-        emit parent.readinessChanged(newReadiness);
-    }
-};
-
-Connection::Connection(const QString& serviceName,
-                       const QString& objectPath,
-                       QObject* parent)
-    : StatefulDBusProxy(QDBusConnection::sessionBus(), serviceName,
-          objectPath, parent),
-      mPriv(new Private(*this))
-{
-    mPriv->startIntrospection();
-}
-
-Connection::Connection(const QDBusConnection& connection,
-                       const QString& serviceName,
-                       const QString& objectPath,
-                       QObject* parent)
-    : StatefulDBusProxy(connection, serviceName, objectPath, parent),
-      mPriv(new Private(*this))
-{
-    mPriv->startIntrospection();
-}
-
-Connection::~Connection()
-{
-    delete mPriv;
-}
-
-Connection::Readiness Connection::readiness() const
-{
-    return mPriv->readiness;
-}
-
-uint Connection::status() const
-{
-    if (mPriv->readiness == ReadinessJustCreated)
-        warning() << "Connection::status() used with readiness ReadinessJustCreated";
-
-    return mPriv->status;
-}
-
-uint Connection::statusReason() const
-{
-    if (mPriv->readiness == ReadinessJustCreated)
-        warning() << "Connection::statusReason() used with readiness ReadinessJustCreated";
-
-    return mPriv->statusReason;
-}
-
-QStringList Connection::interfaces() const
-{
-    // Different check than the others, because the optional interface getters
-    // may be used internally with the knowledge about getting the interfaces
-    // list, so we don't want this to cause warnings.
-    if (mPriv->readiness != ReadinessNotYetConnected && mPriv->readiness != ReadinessFull && mPriv->interfaces.empty())
-        warning() << "Connection::interfaces() used possibly before the list of interfaces has been received";
-    else if (mPriv->readiness == ReadinessDead)
-        warning() << "Connection::interfaces() used with readiness ReadinessDead";
-
-    return mPriv->interfaces;
-}
-
-uint Connection::aliasFlags() const
-{
-    if (mPriv->readiness != ReadinessFull)
-        warning() << "Connection::aliasFlags() used with readiness" << mPriv->readiness << "!= ReadinessFull";
-    else if (!interfaces().contains(TELEPATHY_INTERFACE_CONNECTION_INTERFACE_ALIASING))
-        warning() << "Connection::aliasFlags() used without the remote object supporting the Aliasing interface";
-
-    return mPriv->aliasFlags;
-}
-
-StatusSpecMap Connection::presenceStatuses() const
-{
-    if (mPriv->readiness != ReadinessFull)
-        warning() << "Connection::presenceStatuses() used with readiness" << mPriv->readiness << "!= ReadinessFull";
-    else if (!interfaces().contains(TELEPATHY_INTERFACE_CONNECTION_INTERFACE_PRESENCE))
-        warning() << "Connection::presenceStatuses() used without the remote object supporting the Presence interface";
-
-    return mPriv->presenceStatuses;
-}
-
-SimpleStatusSpecMap Connection::simplePresenceStatuses() const
-{
-    if (mPriv->readiness != ReadinessNotYetConnected && mPriv->readiness != ReadinessFull)
-        warning() << "Connection::simplePresenceStatuses() used with readiness" << mPriv->readiness << "not in (ReadinessNotYetConnected, ReadinessFull)";
-    else if (!interfaces().contains(TELEPATHY_INTERFACE_CONNECTION_INTERFACE_SIMPLE_PRESENCE))
-        warning() << "Connection::simplePresenceStatuses() used without the remote object supporting the SimplePresence interface";
-
-    return mPriv->simplePresenceStatuses;
-}
-
-void Connection::onStatusChanged(uint status, uint reason)
-{
-    if (status == ConnectionStatusConnected &&
-        mPriv->status != ConnectionStatusConnecting) {
-        // CMs aren't meant to go straight from Disconnected to
-        // Connected; recover by faking Connecting
-        warning() << "Non-compliant CM - went straight to CONNECTED!";
-        onStatusChanged(ConnectionStatusConnecting, reason);
-    }
-
-    debug() << "Status changed from" << mPriv->status << "to" << status << "for reason" << reason;
-
-    mPriv->status = status;
-    mPriv->statusReason = reason;
-
-    switch (status) {
-        case ConnectionStatusConnected:
-            debug() << "Performing introspection for the Connected status";
-            mPriv->introspectQueue.enqueue(&Private::introspectMain);
-            mPriv->continueIntrospection();
-            break;
-
-        case ConnectionStatusConnecting:
-            if (mPriv->readiness < ReadinessConnecting)
-                mPriv->changeReadiness(ReadinessConnecting);
-            else
-                warning() << "Got unexpected status change to Connecting";
-            break;
-
-        case ConnectionStatusDisconnected:
-            if (mPriv->readiness != ReadinessDead)
-                mPriv->changeReadiness(ReadinessDead);
-            else
-                warning() << "Got unexpected status change to Disconnected";
-            break;
-
-        default:
-            warning() << "Unknown connection status" << status;
-            break;
-    }
-}
-
-void Connection::gotStatus(QDBusPendingCallWatcher* watcher)
-{
-    QDBusPendingReply<uint> reply = *watcher;
-
-    if (reply.isError()) {
-        warning().nospace() << "GetStatus() failed with " << reply.error().name() << ": " << reply.error().message();
-        mPriv->changeReadiness(ReadinessDead);
-        return;
-    }
-
-    uint status = reply.value();
-
-    debug() << "Got connection status" << status;
-    mPriv->status = status;
-
-    // Don't do any introspection yet if the connection is in the Connecting
-    // state; the StatusChanged handler will take care of doing that, if the
-    // connection ever gets to the Connected state.
-    if (status == ConnectionStatusConnecting) {
-        debug() << "Not introspecting yet because the connection is currently Connecting";
-        mPriv->changeReadiness(ReadinessConnecting);
-        return;
-    }
-
-    if (status == ConnectionStatusDisconnected) {
-        debug() << "Performing introspection for the Disconnected status";
-        mPriv->initialIntrospection = true;
-    } else {
-        if (status != ConnectionStatusConnected) {
-            warning() << "Not performing introspection for unknown status" << status;
-            return;
-        } else {
-            debug() << "Performing introspection for the Connected status";
-        }
-    }
-
-    mPriv->introspectQueue.enqueue(&Private::introspectMain);
-    mPriv->continueIntrospection();
-}
-
-void Connection::gotInterfaces(QDBusPendingCallWatcher* watcher)
-{
-    QDBusPendingReply<QStringList> reply = *watcher;
-
-    if (!reply.isError()) {
-        mPriv->interfaces = reply.value();
-        debug() << "Got reply to GetInterfaces():" << mPriv->interfaces;
-    } else {
-        warning().nospace() << "GetInterfaces() failed with " << reply.error().name() << ": " << reply.error().message() << " - assuming no new interfaces";
-    }
-
-    for (QStringList::const_iterator i  = mPriv->interfaces.constBegin();
-                                     i != mPriv->interfaces.constEnd();
-                                     ++i) {
-        void (Private::*introspectFunc)() = 0;
-
-        if (*i == TELEPATHY_INTERFACE_CONNECTION_INTERFACE_ALIASING)
-            introspectFunc = &Private::introspectAliasing;
-        else if (*i == TELEPATHY_INTERFACE_CONNECTION_INTERFACE_PRESENCE)
-            introspectFunc = &Private::introspectPresence;
-        else if (*i == TELEPATHY_INTERFACE_CONNECTION_INTERFACE_SIMPLE_PRESENCE)
-            introspectFunc = &Private::introspectSimplePresence;
-
-        if (introspectFunc)
-            mPriv->introspectQueue.enqueue(introspectFunc);
-    }
-
-    mPriv->continueIntrospection();
-}
-
-void Connection::gotAliasFlags(QDBusPendingCallWatcher* watcher)
-{
-    QDBusPendingReply<uint> reply = *watcher;
-
-    if (!reply.isError()) {
-        mPriv->aliasFlags = static_cast<ConnectionAliasFlag>(reply.value());
-        debug().nospace() << "Got alias flags 0x" << hex << mPriv->aliasFlags;
-    } else {
-        warning().nospace() << "GetAliasFlags() failed with " << reply.error().name() << ": " << reply.error().message();
-    }
-
-    mPriv->continueIntrospection();
-}
-
-void Connection::gotStatuses(QDBusPendingCallWatcher* watcher)
-{
-    QDBusPendingReply<StatusSpecMap> reply = *watcher;
-
-    if (!reply.isError()) {
-        mPriv->presenceStatuses = reply.value();
-        debug() << "Got" << mPriv->presenceStatuses.size() << "legacy presence statuses";
-    } else {
-        warning().nospace() << "GetStatuses() failed with " << reply.error().name() << ": " << reply.error().message();
-    }
-
-    mPriv->continueIntrospection();
-}
-
-void Connection::gotSimpleStatuses(QDBusPendingCallWatcher* watcher)
-{
-    QDBusPendingReply<QDBusVariant> reply = *watcher;
-
-    if (!reply.isError()) {
-        mPriv->simplePresenceStatuses = qdbus_cast<SimpleStatusSpecMap>(reply.value().variant());
-        debug() << "Got" << mPriv->simplePresenceStatuses.size() << "simple presence statuses";
-    } else {
-        warning().nospace() << "Getting simple presence statuses failed with " << reply.error().name() << ": " << reply.error().message();
-    }
-
-    mPriv->continueIntrospection();
-}
-
-ConnectionInterface* Connection::baseInterface() const
-{
-    Q_ASSERT(mPriv->baseInterface != 0);
-    return mPriv->baseInterface;
-}
-
-PendingChannel* Connection::requestChannel(const QString& channelType, uint handleType, uint handle)
-{
-    debug() << "Requesting a Channel with type" << channelType << "and handle" << handle << "of type" << handleType;
-
-    PendingChannel* channel =
-        new PendingChannel(this, channelType, handleType, handle);
-    QDBusPendingCallWatcher* watcher =
-        new QDBusPendingCallWatcher(mPriv->baseInterface->RequestChannel(channelType, handleType, handle, true), channel);
-
-    channel->connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
-                              SLOT(onCallFinished(QDBusPendingCallWatcher*)));
-
-    return channel;
-}
-
-#if 0
-// FIXME: this is a 1:1 mapping of the method from TpPrototype, but
-// most likely what we really want as a high-level API is something
-// more analogous to tp_connection_call_when_ready() in telepathy-glib
-PendingOperation* Connection::requestConnect()
-{
-    return new PendingVoidMethodCall(this, baseInterface()->Connect());
-}
-#endif
-
-PendingOperation* Connection::requestDisconnect()
-{
-    return new PendingVoidMethodCall(this, baseInterface()->Disconnect());
-}
-
-}
-}
diff --git a/TelepathyQt4/cli-connection.h b/TelepathyQt4/cli-connection.h
deleted file mode 100644
index acf355a..0000000
--- a/TelepathyQt4/cli-connection.h
+++ /dev/null
@@ -1,472 +0,0 @@
-/*
- * This file is part of TelepathyQt4
- *
- * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
- * Copyright (C) 2008 Nokia Corporation
- *
- * 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.
- *
- * 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.
- *
- * 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 St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#ifndef _TelepathyQt4_cli_connection_h_HEADER_GUARD_
-#define _TelepathyQt4_cli_connection_h_HEADER_GUARD_
-
-/**
- * \addtogroup clientsideproxies Client-side proxies
- *
- * Proxy objects representing remote service objects accessed via D-Bus.
- *
- * In addition to providing direct access to methods, signals and properties
- * exported by the remote objects, some of these proxies offer features like
- * automatic inspection of remote object capabilities, property tracking,
- * backwards compatibility helpers for older services and other utilities.
- */
-
-/**
- * \defgroup clientconn Connection proxies
- * \ingroup clientsideproxies
- *
- * Proxy objects representing remote Telepathy Connections and their optional
- * interfaces.
- */
-
-namespace Telepathy {
-namespace Client {
-class Connection;
-}
-}
-
-#include <TelepathyQt4/_gen/cli-connection.h>
-
-#include <QDBusPendingCallWatcher>
-#include <QStringList>
-
-#include <TelepathyQt4/Constants>
-#include <TelepathyQt4/Client/Channel>
-#include <TelepathyQt4/Client/DBus>
-#include <TelepathyQt4/Client/DBusProxy>
-#include <TelepathyQt4/Client/OptionalInterfaceFactory>
-#include <TelepathyQt4/Client/PendingOperation>
-
-#include "cli-pending-channel.h"
-
-namespace Telepathy
-{
-namespace Client
-{
-
-/**
- * \class Connection
- * \ingroup clientconn
- * \headerfile <TelepathyQt4/cli-connection.h> <TelepathyQt4/Client/Connection>
- *
- * High-level proxy object for accessing remote %Telepathy %Connection objects.
- *
- * It adds the following features compared to using ConnectionInterface
- * directly:
- * <ul>
- *  <li>%Connection status tracking</li>
- *  <li>Getting the list of supported interfaces automatically</li>
- *  <li>Getting the alias flags automatically</li>
- *  <li>Getting the valid presence statuses automatically</li>
- *  <li>Shared optional interface proxy instances</li>
- * </ul>
- *
- * The remote object state accessor functions on this object (status(),
- * statusReason(), aliasFlags(), and so on) don't make any %DBus calls; instead,
- * they return values cached from a previous introspection run. The
- * introspection process populates their values in the most efficient way
- * possible based on what the service implements.  Their return value is mostly
- * undefined until the introspection process is completed; a readiness change to
- * #ReadinessFull indicates that the introspection process is finished. See the
- * individual accessor descriptions for details on which functions can be used
- * in the different states.
- */
-class Connection : public StatefulDBusProxy, private OptionalInterfaceFactory
-{
-    Q_OBJECT
-    Q_ENUMS(Readiness);
-
-public:
-    /**
-     * Describes readiness of the Connection for usage. The readiness depends
-     * on the state of the remote object. In suitable states, an asynchronous
-     * introspection process is started, and the Connection becomes more ready
-     * when that process is completed.
-     */
-    enum Readiness {
-        /**
-         * The object has just been created and introspection is still in
-         * progress. No functionality is available.
-         *
-         * The readiness can change to any other state depending on the result
-         * of the initial state query to the remote object.
-         */
-        ReadinessJustCreated = 0,
-
-        /**
-         * The remote object is in the Disconnected state and introspection
-         * relevant to that state has been completed.
-         *
-         * This state is useful for being able to set your presence status
-         * (through the SimplePresence interface) before connecting. Most other
-         * functionality is unavailable, though.
-         *
-         * The readiness can change to ReadinessConnecting and ReadinessDead.
-         */
-        ReadinessNotYetConnected = 5,
-
-        /**
-         * The remote object is in the Connecting state. Most functionality is
-         * unavailable.
-         *
-         * The readiness can change to ReadinessFull and ReadinessDead.
-         */
-        ReadinessConnecting = 10,
-
-        /**
-         * The connection is in the Connected state and all introspection
-         * has been completed. Most functionality is available.
-         *
-         * The readiness can change to ReadinessDead.
-         */
-        ReadinessFull = 15,
-
-        /**
-         * The remote object has gone into a state where it can no longer be
-         * used. No functionality is available.
-         *
-         * No further readiness changes are possible.
-         */
-        ReadinessDead = 20,
-
-        _ReadinessInvalid = 0xffff
-    };
-
-    /**
-     * Creates a Connection associated with the given object on the session bus.
-     *
-     * \param serviceName Name of the service the object is on.
-     * \param objectPath  Path to the object on the service.
-     * \param parent      Passed to the parent class constructor.
-     */
-    Connection(const QString& serviceName,
-               const QString& objectPath,
-               QObject* parent = 0);
-
-    /**
-     * Creates a Connection associated with the given object on the given bus.
-     *
-     * \param connection  The bus via which the object can be reached.
-     * \param serviceName Name of the service the object is on.
-     * \param objectPath  Path to the object on the service.
-     * \param parent      Passed to the parent class constructor.
-     */
-    Connection(const QDBusConnection& connection,
-               const QString &serviceName,
-               const QString &objectPath,
-               QObject* parent = 0);
-
-    /**
-     * Class destructor.
-     */
-    ~Connection();
-
-    /**
-     * Returns the current readiness of the Connection.
-     *
-     * \return The readiness, as defined in #Readiness.
-     */
-    Readiness readiness() const;
-
-    /**
-     * Returns the connection's status.
-     *
-     * The returned value may have changed whenever readinessChanged() is
-     * emitted. The value is valid in all states except for
-     * #ReadinessJustCreated.
-     *
-     * \return The status, as defined in #ConnectionStatus.
-     */
-    uint status() const;
-
-    /**
-     * Returns the reason for the connection's status (which is returned by
-     * status()). The validity and change rules are the same as for status().
-     *
-     * \return The reason, as defined in #ConnectionStatusReason.
-     */
-    uint statusReason() const;
-
-    /**
-     * Returns a list of optional interfaces supported by this object. The
-     * contents of the list is undefined unless the Connection has readiness
-     * #ReadinessNotYetConnected or #ReadinessFull. The returned value stays
-     * constant for the entire time the connection spends in each of these
-     * states; however interfaces might have been added to the supported set by
-     * the time #ReadinessFull is reached.
-     *
-     * \return Names of the supported interfaces.
-     */
-    QStringList interfaces() const;
-
-    /**
-     * Returns the bitwise OR of flags detailing the behavior of the Aliasing
-     * interface on the remote object.
-     *
-     * The returned value is undefined unless the Connection has readiness
-     * #ReadinessFull and the list returned by interfaces() contains
-     * %TELEPATHY_INTERFACE_CONNECTION_INTERFACE_ALIASING.
-     *
-     * \return Bitfield of flags, as specified in #ConnectionAliasFlag.
-     */
-    uint aliasFlags() const;
-
-    /**
-     * Returns a dictionary of presence statuses valid for use with the legacy
-     * Telepathy Presence interface on the remote object.
-     *
-     * The returned value is undefined unless the Connection has readiness
-     * #ReadinessFull and the list returned by interfaces() contains
-     * %TELEPATHY_INTERFACE_CONNECTION_INTERFACE_PRESENCE.
-     *
-     * \return Dictionary from string identifiers to structs for each valid status.
-     */
-    StatusSpecMap presenceStatuses() const;
-
-    /**
-     * Returns a dictionary of presence statuses valid for use with the new(er)
-     * Telepathy SimplePresence interface on the remote object.
-     *
-     * The value is undefined if the list returned by interfaces() doesn't
-     * contain %TELEPATHY_INTERFACE_CONNECTION_INTERFACE_SIMPLE_PRESENCE.
-     *
-     * The value will stay fixed for the whole time the connection stays with
-     * readiness #ReadinessNotYetConnected, but may have changed arbitrarily
-     * during the time the Connection spends in readiness #ReadinessConnecting,
-     * again staying fixed for the entire time in #ReadinessFull.
-     *
-     * \return Dictionary from string identifiers to structs for each valid
-     * status.
-     */
-    SimpleStatusSpecMap simplePresenceStatuses() const;
-
-    /**
-     * Specifies if the interface being supported by the remote object should be
-     * checked by optionalInterface() and the convenience functions for it.
-     */
-    enum InterfaceSupportedChecking
-    {
-        /**
-         * Don't return an interface instance unless it can be guaranteed that
-         * the remote object actually implements the interface.
-         */
-        CheckInterfaceSupported,
-
-        /**
-         * Return an interface instance even if it can't be verified that the
-         * remote object supports the interface.
-         */
-        BypassInterfaceCheck
-    };
-
-    /**
-     * Returns a pointer to a valid instance of a given %Connection optional
-     * interface class, associated with the same remote object the Connection is
-     * associated with, and destroyed at the same time the Connection is
-     * destroyed.
-     *
-     * If the list returned by interfaces() doesn't contain the name of the
-     * interface requested <code>0</code> is returned. This check can be
-     * bypassed by specifying #BypassInterfaceCheck for <code>check</code>, in
-     * which case a valid instance is always returned.
-     *
-     * If the object doesn't have readiness #ReadinessNotYetConnected or
-     * #ReadinessFull, the list returned by interfaces() isn't guaranteed to yet
-     * represent the full set of interfaces supported by the remote object.
-     * Hence the check might fail even if the remote object actually supports
-     * the requested interface; using #BypassInterfaceCheck is suggested when
-     * the Connection is not suitably ready.
-     *
-     * \see OptionalInterfaceFactory::interface
-     *
-     * \tparam Interface Class of the optional interface to get.
-     * \param check Should an instance be returned even if it can't be
-     *              determined that the remote object supports the
-     *              requested interface.
-     * \return Pointer to an instance of the interface class, or <code>0</code>.
-     */
-    template <class Interface>
-    inline Interface* optionalInterface(InterfaceSupportedChecking check = CheckInterfaceSupported) const
-    {
-        // Check for the remote object supporting the interface
-        QString name(Interface::staticInterfaceName());
-        if (check == CheckInterfaceSupported && !interfaces().contains(name))
-            return 0;
-
-        // If present or forced, delegate to OptionalInterfaceFactory
-        return OptionalInterfaceFactory::interface<Interface>(*baseInterface());
-    }
-
-    /**
-     * Convenience function for getting an Aliasing interface proxy.
-     *
-     * \param check Passed to optionalInterface()
-     * \return <code>optionalInterface<ConnectionInterfaceAliasingInterface>(check)</code>
-     */
-    inline ConnectionInterfaceAliasingInterface* aliasingInterface(InterfaceSupportedChecking check = CheckInterfaceSupported) const
-    {
-        return optionalInterface<ConnectionInterfaceAliasingInterface>(check);
-    }
-
-    /**
-     * Convenience function for getting an Avatars interface proxy.
-     *
-     * \param check Passed to optionalInterface()
-     * \return <code>optionalInterface<ConnectionInterfaceAvatarsInterface>(check)</code>
-     */
-    inline ConnectionInterfaceAvatarsInterface* avatarsInterface(InterfaceSupportedChecking check = CheckInterfaceSupported) const
-    {
-        return optionalInterface<ConnectionInterfaceAvatarsInterface>(check);
-    }
-
-    /**
-     * Convenience function for getting a Capabilities interface proxy.
-     *
-     * \param check Passed to optionalInterface()
-     * \return <code>optionalInterface<ConnectionInterfaceCapabilitiesInterface>(check)</code>
-     */
-    inline ConnectionInterfaceCapabilitiesInterface* capabilitiesInterface(InterfaceSupportedChecking check = CheckInterfaceSupported) const
-    {
-        return optionalInterface<ConnectionInterfaceCapabilitiesInterface>(check);
-    }
-
-    /**
-     * Convenience function for getting a Presence interface proxy.
-     *
-     * \param check Passed to optionalInterface()
-     * \return <code>optionalInterface<ConnectionInterfacePresenceInterface>(check)</code>
-     */
-    inline ConnectionInterfacePresenceInterface* presenceInterface(InterfaceSupportedChecking check = CheckInterfaceSupported) const
-    {
-        return optionalInterface<ConnectionInterfacePresenceInterface>(check);
-    }
-
-    /**
-     * Convenience function for getting a SimplePresence interface proxy.
-     *
-     * \param check Passed to optionalInterface()
-     * \return
-     * <code>optionalInterface<ConnectionInterfaceSimplePresenceInterface>(check)</code>
-     */
-    inline ConnectionInterfaceSimplePresenceInterface* simplePresenceInterface(InterfaceSupportedChecking check = CheckInterfaceSupported) const
-    {
-        return optionalInterface<ConnectionInterfaceSimplePresenceInterface>(check);
-    }
-
-    /**
-     * Convenience function for getting a Properties interface proxy. The
-     * Properties interface is not necessarily reported by the services, so a
-     * <code>check</code> parameter is not provided, and the interface is
-     * always assumed to be present.
-     *
-     * \see optionalInterface()
-     *
-     * \return
-     * <code>optionalInterface<DBus::PropertiesInterface>(BypassInterfaceCheck)</code>
-     */
-    inline DBus::PropertiesInterface* propertiesInterface() const
-    {
-        return optionalInterface<DBus::PropertiesInterface>(BypassInterfaceCheck);
-    }
-
-    /**
-     * Asynchronously requests a channel satisfying the given channel type and
-     * communicating with the contact, room, list etc. given by the handle type
-     * and handle.
-     *
-     * Upon completion, the reply to the request can be retrieved through the
-     * returned PendingChannel object. The object also provides access to the
-     * parameters with which the call was made and a signal to connect to to get
-     * notification of the request finishing processing. See the documentation
-     * for that class for more info.
-     *
-     * The returned PendingChannel object should be freed using
-     * its QObject::deleteLater() method after it is no longer used. However,
-     * all PendingChannel objects resulting from requests to a particular
-     * Connection will be freed when the Connection itself is freed. Conversely,
-     * this means that the PendingChannel object should not be used after the
-     * Connection is destroyed.
-     *
-     * \sa PendingChannel
-     *
-     * \param channelType D-Bus interface name of the channel type to request,
-     *                    such as TELEPATHY_INTERFACE_CHANNEL_TYPE_TEXT.
-     * \param handleType Type of the handle given, as specified in #HandleType.
-     * \param handle Handle specifying the remote entity to communicate with.
-     * \return Pointer to a newly constructed PendingChannel object, tracking
-     *         the progress of the request.
-     */
-    PendingChannel* requestChannel(const QString& channelType, uint handleType, uint handle);
-
-    /**
-     * Start an asynchronous request that the connection be disconnected.
-     * The returned PendingOperation object will signal the success or failure
-     * of this request; under normal circumstances, it can be expected to
-     * succeed.
-     *
-     * \return A %PendingOperation, which will emit finished when the
-     *  Disconnect D-Bus method returns.
-     */
-    PendingOperation* requestDisconnect();
-
-Q_SIGNALS:
-    /**
-     * Emitted whenever the readiness of the Connection changes.
-     *
-     * \param newReadiness The new readiness, as defined in #Readiness.
-     */
-    void readinessChanged(uint newReadiness);
-
-public:
-    /**
-     * Get the ConnectionInterface for this Connection.
-     *
-     * FIXME: This method should be protected since the convenience methods
-     * provided by this class should always be used instead. However, they
-     * haven't all been written yet.
-     *
-     * \return A pointer to the existing ConnectionInterface for this
-     *         Connection
-     */
-    ConnectionInterface* baseInterface() const;
-
-private Q_SLOTS:
-    void onStatusChanged(uint, uint);
-    void gotStatus(QDBusPendingCallWatcher* watcher);
-    void gotInterfaces(QDBusPendingCallWatcher* watcher);
-    void gotAliasFlags(QDBusPendingCallWatcher* watcher);
-    void gotStatuses(QDBusPendingCallWatcher* watcher);
-    void gotSimpleStatuses(QDBusPendingCallWatcher* watcher);
-
-private:
-    struct Private;
-    friend struct Private;
-    Private *mPriv;
-};
-
-}
-}
-
-#endif
diff --git a/TelepathyQt4/cli-dbus-proxy.cpp b/TelepathyQt4/cli-dbus-proxy.cpp
deleted file mode 100644
index 9a4d654..0000000
--- a/TelepathyQt4/cli-dbus-proxy.cpp
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * This file is part of TelepathyQt4
- *
- * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
- * Copyright (C) 2008 Nokia Corporation
- *
- * 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.
- *
- * 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.
- *
- * 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 St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#include "cli-dbus-proxy.h"
-
-#include "debug-internal.hpp"
-
-namespace Telepathy
-{
-namespace Client
-{
-
-struct DBusProxy::Private
-{
-    // Public object
-    DBusProxy& parent;
-
-    QDBusConnection dbusConnection;
-    QString busName;
-    QString objectPath;
-
-    Private(const QDBusConnection& dbusConnection, const QString& busName,
-            const QString& objectPath, DBusProxy& p)
-        : parent(p),
-          dbusConnection(dbusConnection),
-          busName(busName),
-          objectPath(objectPath)
-    {
-        debug() << "Creating new DBusProxy";
-    }
-};
-
-DBusProxy::DBusProxy(const QDBusConnection& dbusConnection,
-        const QString& busName, const QString& path, QObject* parent)
- : QObject(parent),
-   mPriv(new Private(dbusConnection, busName, path, *this))
-{
-}
-
-DBusProxy::~DBusProxy()
-{
-    delete mPriv;
-}
-
-QDBusConnection DBusProxy::dbusConnection() const
-{
-    return mPriv->dbusConnection;
-}
-
-QString DBusProxy::objectPath() const
-{
-    return mPriv->objectPath;
-}
-
-QString DBusProxy::busName() const
-{
-    return mPriv->busName;
-}
-
-StatelessDBusProxy::StatelessDBusProxy(const QDBusConnection& dbusConnection,
-        const QString& busName, const QString& objectPath, QObject* parent)
-    : DBusProxy(dbusConnection, busName, objectPath, parent)
-{
-}
-
-StatefulDBusProxy::StatefulDBusProxy(const QDBusConnection& dbusConnection,
-        const QString& busName, const QString& objectPath, QObject* parent)
-    : DBusProxy(dbusConnection, busName, objectPath, parent)
-{
-}
-
-}
-}
-
-#include "cli-dbus-proxy.moc.hpp"
diff --git a/TelepathyQt4/cli-dbus-proxy.h b/TelepathyQt4/cli-dbus-proxy.h
deleted file mode 100644
index 79e4097..0000000
--- a/TelepathyQt4/cli-dbus-proxy.h
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * This file is part of TelepathyQt4
- *
- * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
- * Copyright (C) 2008 Nokia Corporation
- *
- * 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.
- *
- * 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.
- *
- * 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 St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#ifndef _TelepathyQt4_cli_dbus_proxy_h_HEADER_GUARD_
-#define _TelepathyQt4_cli_dbus_proxy_h_HEADER_GUARD_
-
-// FIXME: What groups should this be in/define?
-
-#include <QtDBus/QDBusAbstractInterface>
-#include <QtDBus/QDBusConnection>
-
-namespace Telepathy
-{
-namespace Client
-{
-
-/**
- * \class DBusProxy
- * \ingroup FIXME: what group is it in?
- * \headerfile TelepathyQt4/cli-dbus-proxy.h <TelepathyQt4/Client/DBusProxy>
- *
- * Base class representing a remote object available over D-Bus.
- *
- * All TelepathyQt4 client convenience classes that wrap Telepathy interfaces
- * inherit from this class in order to provide basic D-Bus interface
- * information.
- *
- */
-class DBusProxy : public QObject
-{
-    Q_OBJECT
-
-public:
-    /**
-     * Constructor
-     */
-    DBusProxy(const QDBusConnection& dbusConnection, const QString& busName,
-            const QString& objectPath, QObject* parent = 0);
-
-    /**
-     * Destructor
-     */
-    virtual ~DBusProxy();
-
-    /**
-     * Returns the D-Bus connection through which the remote object is
-     * accessed.
-     *
-     * \return The connection the object is associated with.
-     */
-    QDBusConnection dbusConnection() const;
-
-    /**
-     * Returns the D-Bus bus name (either a unique name or a well-known
-     * name) of the service that provides the remote object.
-     *
-     * \return The service name the object is associated with.
-     */
-    QString busName() const;
-
-    /**
-     * Returns the D-Bus object path of the remote object within the service.
-     *
-     * \return The object path the object is associated with.
-     */
-    QString objectPath() const;
-
-    /**
-     * If this object is usable (has not emitted #invalidated()), returns
-     * <code>true</code>. Otherwise returns <code>false</code>.
-     *
-     * \return <code>true</code> if this object is still fully usable
-     */
-    bool isValid() const;
-
-    /**
-     * If this object is no longer usable (has emitted #invalidated()),
-     * returns the error name indicating the reason it became invalid in a
-     * machine-readable way. Otherwise, returns a null QString.
-     *
-     * \return A D-Bus error name, or QString() if this object is still valid
-     */
-    QString invalidationReason() const;
-
-    /**
-     * If this object is no longer usable (has emitted #invalidated()),
-     * returns a debugging message indicating the reason it became invalid.
-     * Otherwise, returns a null QString.
-     *
-     * \return A debugging message, or QString() if this object is still valid
-     */
-    QString invalidationMessage() const;
-
-Q_SIGNALS:
-    /**
-     * Emitted when this object is no longer usable.
-     *
-     * After this signal is emitted, any D-Bus method calls on the object
-     * will fail, but it may be possible to retrieve information that has
-     * already been retrieved and cached.
-     *
-     * \param proxy This proxy
-     * \param errorName A D-Bus error name (a string in a subset
-     *                  of ASCII, prefixed with a reversed domain name)
-     * \param errorMessage A debugging message associated with the error
-     */
-    void invalidated(DBusProxy* proxy, QString errorName,
-            QString errorMessage);
-
-private:
-    struct Private;
-    friend struct Private;
-    Private *mPriv;
-};
-
-/**
- * \class StatelessDBusProxy
- * \ingroup FIXME: what group is it in?
- * \headerfile TelepathyQt4/cli-dbus-proxy.h <TelepathyQt4/Client/DBusProxy>
- *
- * Base class representing a remote object whose API is basically stateless.
- * These objects can remain valid even if the service providing them exits
- * and is restarted.
- *
- * Examples in Telepathy include the AccountManager, Account and
- * ConnectionManager.
- */
-class StatelessDBusProxy : public DBusProxy
-{
-    Q_OBJECT
-
-public:
-    StatelessDBusProxy(const QDBusConnection& dbusConnection,
-        const QString& busName, const QString& objectPath,
-        QObject* parent = 0);
-
-private:
-    struct Private;
-    friend struct Private;
-    Private *mPriv;
-};
-
-/**
- * \class StatefulDBusProxy
- * \ingroup FIXME: what group is it in?
- * \headerfile TelepathyQt4/cli-dbus-proxy.h <TelepathyQt4/Client/DBusProxy>
- *
- * Base class representing a remote object whose API is stateful. These
- * objects do not remain useful if the service providing them exits or
- * crashes, so they emit #invalidated() if this happens.
- *
- * Examples in Telepathy include the Connection and Channel.
- */
-class StatefulDBusProxy : public DBusProxy
-{
-    Q_OBJECT
-
-public:
-    StatefulDBusProxy(const QDBusConnection& dbusConnection,
-        const QString& busName, const QString& objectPath,
-        QObject* parent = 0);
-
-private:
-    struct Private;
-    friend struct Private;
-    Private *mPriv;
-};
-
-}
-}
-
-#endif
diff --git a/TelepathyQt4/cli-dbus.cpp b/TelepathyQt4/cli-dbus.cpp
deleted file mode 100644
index c479e6d..0000000
--- a/TelepathyQt4/cli-dbus.cpp
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * This file is part of TelepathyQt4
- *
- * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
- * Copyright (C) 2008 Nokia Corporation
- *
- * 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.
- *
- * 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.
- *
- * 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 St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#include <TelepathyQt4/_gen/cli-dbus-body.hpp>
-#include <TelepathyQt4/_gen/cli-dbus.moc.hpp>
diff --git a/TelepathyQt4/cli-dbus.h b/TelepathyQt4/cli-dbus.h
deleted file mode 100644
index 5b130e4..0000000
--- a/TelepathyQt4/cli-dbus.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * This file is part of TelepathyQt4
- *
- * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
- * Copyright (C) 2008 Nokia Corporation
- *
- * 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.
- *
- * 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.
- *
- * 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 St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#ifndef _TelepathyQt4_cli_dbus_h_HEADER_GUARD_
-#define _TelepathyQt4_cli_dbus_h_HEADER_GUARD_
-
-/**
- * \addtogroup clientsideproxies Client-side proxies
- *
- * Proxy objects representing remote service objects accessed via D-Bus.
- *
- * In addition to providing direct access to methods, signals and properties
- * exported by the remote objects, some of these proxies offer features like
- * automatic inspection of remote object capabilities, property tracking,
- * backwards compatibility helpers for older services and other utilities.
- */
-
-/**
- * \defgroup clientdbus Generic D-Bus proxies
- * \ingroup clientsideproxies
- *
- * Proxy objects representing well-known generic D-Bus interfaces on remote
- * objects. Note that QDBus already has QDBusConnectionInterface for accessing
- * the bus daemon, so in the parts where there is an overlap in the
- * functionality, using the QDBus proxy should be given consideration instead
- * of blindly using the proxy provided here.
- */
-
-#include <TelepathyQt4/_gen/cli-dbus.h>
-
-#endif
diff --git a/TelepathyQt4/cli-media-session-handler.cpp b/TelepathyQt4/cli-media-session-handler.cpp
deleted file mode 100644
index efcdba8..0000000
--- a/TelepathyQt4/cli-media-session-handler.cpp
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * This file is part of TelepathyQt4
- *
- * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
- * Copyright (C) 2008 Nokia Corporation
- *
- * 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.
- *
- * 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.
- *
- * 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 St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#include <TelepathyQt4/_gen/cli-media-session-handler-body.hpp>
-#include <TelepathyQt4/_gen/cli-media-session-handler.moc.hpp>
diff --git a/TelepathyQt4/cli-media-session-handler.h b/TelepathyQt4/cli-media-session-handler.h
deleted file mode 100644
index e566c60..0000000
--- a/TelepathyQt4/cli-media-session-handler.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * This file is part of TelepathyQt4
- *
- * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
- * Copyright (C) 2008 Nokia Corporation
- *
- * 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.
- *
- * 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.
- *
- * 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 St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#ifndef _TelepathyQt4_cli_media_session_handler_h_HEADER_GUARD_
-#define _TelepathyQt4_cli_media_session_handler_h_HEADER_GUARD_
-
-/**
- * \addtogroup clientsideproxies Client-side proxies
- *
- * Proxy objects representing remote service objects accessed via D-Bus.
- *
- * In addition to providing direct access to methods, signals and properties
- * exported by the remote objects, some of these proxies offer features like
- * automatic inspection of remote object capabilities, property tracking,
- * backwards compatibility helpers for older services and other utilities.
- */
-
-/**
- * \defgroup clientmsesh Media session handler proxies
- * \ingroup clientsideproxies
- *
- * Proxy objects representing remote Telepathy MediaSessionHandler objects.
- */
-
-#include <TelepathyQt4/_gen/cli-media-session-handler.h>
-
-#endif
diff --git a/TelepathyQt4/cli-media-stream-handler.cpp b/TelepathyQt4/cli-media-stream-handler.cpp
deleted file mode 100644
index c8d5170..0000000
--- a/TelepathyQt4/cli-media-stream-handler.cpp
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * This file is part of TelepathyQt4
- *
- * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
- * Copyright (C) 2008 Nokia Corporation
- *
- * 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.
- *
- * 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.
- *
- * 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 St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#include <TelepathyQt4/_gen/cli-media-stream-handler-body.hpp>
-#include <TelepathyQt4/_gen/cli-media-stream-handler.moc.hpp>
diff --git a/TelepathyQt4/cli-media-stream-handler.h b/TelepathyQt4/cli-media-stream-handler.h
deleted file mode 100644
index 58903b7..0000000
--- a/TelepathyQt4/cli-media-stream-handler.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * This file is part of TelepathyQt4
- *
- * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
- * Copyright (C) 2008 Nokia Corporation
- *
- * 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.
- *
- * 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.
- *
- * 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 St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#ifndef _TelepathyQt4_cli_media_stream_handler_h_HEADER_GUARD_
-#define _TelepathyQt4_cli_media_stream_handler_h_HEADER_GUARD_
-
-/**
- * \addtogroup clientsideproxies Client-side proxies
- *
- * Proxy objects representing remote service objects accessed via D-Bus.
- *
- * In addition to providing direct access to methods, signals and properties
- * exported by the remote objects, some of these proxies offer features like
- * automatic inspection of remote object capabilities, property tracking,
- * backwards compatibility helpers for older services and other utilities.
- */
-
-/**
- * \defgroup clientmstrh Media stream handler proxies
- * \ingroup clientsideproxies
- *
- * Proxy objects representing remote Telepathy MediaStreamHandler objects.
- */
-
-#include <TelepathyQt4/_gen/cli-media-stream-handler.h>
-
-#endif
diff --git a/TelepathyQt4/cli-optional-interface-factory.cpp b/TelepathyQt4/cli-optional-interface-factory.cpp
deleted file mode 100644
index 9406fe0..0000000
--- a/TelepathyQt4/cli-optional-interface-factory.cpp
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * This file is part of TelepathyQt4
- *
- * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
- * Copyright (C) 2008 Nokia Corporation
- *
- * 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.
- *
- * 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.
- *
- * 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 St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#include "cli-optional-interface-factory.h"
-
-#include <QMap>
-#include <QString>
-
-#include "debug-internal.hpp"
-
-namespace Telepathy
-{
-namespace Client
-{
-
-struct OptionalInterfaceFactory::Private
-{
-    QMap<QString, QDBusAbstractInterface*> interfaces;
-};
-
-OptionalInterfaceFactory::OptionalInterfaceFactory()
-    : mPriv(new Private())
-{
-    debug() << "Constructing OptionalInterfaceFactory";
-}
-
-OptionalInterfaceFactory::~OptionalInterfaceFactory()
-{
-    debug() << "Destroying OptionalInterfaceFactory";
-
-    for (QMap<QString, QDBusAbstractInterface*>::iterator i = mPriv->interfaces.begin();
-                                                          i != mPriv->interfaces.end();
-                                                          ++i) {
-        debug().nospace() << " ~" << i.key();
-        delete i.value();
-    }
-
-    delete mPriv;
-}
-
-QDBusAbstractInterface* OptionalInterfaceFactory::getCached(const QString& name) const
-{
-    if (mPriv->interfaces.contains(name)) {
-        debug() << "Returning cached interface for" << name;
-        return mPriv->interfaces.value(name);
-    } else {
-        debug() << "No interface found for" << name;
-        return 0;
-    }
-}
-
-void OptionalInterfaceFactory::cache(QDBusAbstractInterface* interface) const
-{
-    QString name = interface->interface();
-    Q_ASSERT(!mPriv->interfaces.contains(name));
-
-    debug() << "Caching interface" << name;
-    mPriv->interfaces[name] = interface;
-}
-
-}
-}
diff --git a/TelepathyQt4/cli-optional-interface-factory.h b/TelepathyQt4/cli-optional-interface-factory.h
deleted file mode 100644
index ce6256c..0000000
--- a/TelepathyQt4/cli-optional-interface-factory.h
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * This file is part of TelepathyQt4
- *
- * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
- * Copyright (C) 2008 Nokia Corporation
- *
- * 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.
- *
- * 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.
- *
- * 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 St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#ifndef _TelepathyQt4_cli_optional_interface_factory_h_HEADER_GUARD_
-#define _TelepathyQt4_cli_optional_interface_factory_h_HEADER_GUARD_
-
-/**
- * \addtogroup clientsideproxies Client-side proxies
- *
- * Proxy objects representing remote service objects accessed via D-Bus.
- *
- * In addition to providing direct access to methods, signals and properties
- * exported by the remote objects, some of these proxies offer features like
- * automatic inspection of remote object capabilities, property tracking,
- * backwards compatibility helpers for older services and other utilities.
- */
-
-#include <QtGlobal>
-
-#include <QDBusAbstractInterface>
-
-namespace Telepathy
-{
-namespace Client
-{
-
-/**
- * \class OptionalInterfaceFactory
- * \ingroup clientsideproxies
- * \headerfile <TelepathyQt4/cli-optional-interface-factory.h> <TelepathyQt4/Client/OptionalInterfaceFactory>
- *
- * Implementation helper class for high-level proxy classes willing to offer
- * access to shared instances of interface proxies for optional interfaces.
- *
- * This class is included in the public API for the benefit of high-level
- * proxies in extensions.
- */
-class OptionalInterfaceFactory
-{
-    public:
-        /**
-         * Class constructor.
-         */
-        OptionalInterfaceFactory();
-
-        /**
-         * Class destructor.
-         *
-         * Frees all interface instances constructed by this factory.
-         */
-        ~OptionalInterfaceFactory();
-
-        /**
-         * Return a pointer to a valid instance of a interface class, associated
-         * with the same remote object as the given main interface instance. The
-         * given main interface must be of the class the optional interface is
-         * generated for (for eg. ChannelInterfaceGroupInterface this means
-         * ChannelInterface) or a subclass.
-         *
-         * First invocation of this method for a particular optional interface
-         * class will construct the instance; subsequent calls will return a
-         * pointer to the same instance.
-         *
-         * The returned instance is freed when the factory is destroyed; using
-         * it after destroying the factory will likely produce a crash. As the
-         * instance is shared, it should not be freed directly.
-         *
-         * \tparam OptionalInterface Class of the interface instance to get.
-         * \tparam MainInterface Class of the main interface.
-         * \param mainInterface Main interface instance to use.
-         * \return A pointer to an optional interface instance.
-         */
-        template <typename OptionalInterface, typename MainInterface>
-        inline OptionalInterface* interface(const MainInterface& mainInterface) const
-        {
-            // Check that the types given are both subclasses of QDBusAbstractInterface
-            QDBusAbstractInterface* mainInterfaceMustBeASubclassOfQDBusAbstractInterface = static_cast<MainInterface*>(NULL);
-            QDBusAbstractInterface* optionalInterfaceMustBeASubclassOfQDBusAbstractInterface = static_cast<OptionalInterface*>(NULL);
-            Q_UNUSED(mainInterfaceMustBeASubclassOfQDBusAbstractInterface);
-            Q_UNUSED(optionalInterfaceMustBeASubclassOfQDBusAbstractInterface);
-
-            // If there is a interface cached already, return it
-            QString name(OptionalInterface::staticInterfaceName());
-            QDBusAbstractInterface* cached = getCached(name);
-            if (cached)
-                return static_cast<OptionalInterface*>(cached);
-
-            // Otherwise, cache and return a newly constructed proxy
-            OptionalInterface* interface = new OptionalInterface(mainInterface, 0);
-            cache(interface);
-            return interface;
-        }
-
-    private:
-        QDBusAbstractInterface* getCached(const QString& name) const;
-        void cache(QDBusAbstractInterface* interface) const;
-
-        struct Private;
-        Private* mPriv;
-};
-
-}
-}
-
-#endif
diff --git a/TelepathyQt4/cli-pending-channel.cpp b/TelepathyQt4/cli-pending-channel.cpp
deleted file mode 100644
index 22fccc2..0000000
--- a/TelepathyQt4/cli-pending-channel.cpp
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * This file is part of TelepathyQt4
- *
- * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
- * Copyright (C) 2008 Nokia Corporation
- *
- * 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.
- *
- * 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.
- *
- * 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 St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#include "cli-pending-channel.h"
-
-#include "cli-pending-channel.moc.hpp"
-
-#include "debug-internal.hpp"
-
-namespace Telepathy
-{
-namespace Client
-{
-
-struct PendingChannel::Private
-{
-    QString channelType;
-    uint handleType;
-    uint handle;
-    QDBusObjectPath objectPath;
-};
-
-PendingChannel::PendingChannel(Connection* connection, const QString& channelType, uint handleType, uint handle)
-    : PendingOperation(connection), mPriv(new Private)
-{
-    mPriv->channelType = channelType;
-    mPriv->handleType = handleType;
-    mPriv->handle = handle;
-}
-
-PendingChannel::~PendingChannel()
-{
-    delete mPriv;
-}
-
-Connection* PendingChannel::connection() const
-{
-    return qobject_cast<Connection*>(parent());
-}
-
-const QString& PendingChannel::channelType() const
-{
-    return mPriv->channelType;
-}
-
-uint PendingChannel::handleType() const
-{
-    return mPriv->handleType;
-}
-
-uint PendingChannel::handle() const
-{
-    return mPriv->handle;
-}
-
-Channel* PendingChannel::channel(QObject* parent) const
-{
-    if (!isFinished()) {
-        warning() << "PendingChannel::channel called before finished, returning 0";
-        return 0;
-    } else if (!isValid()) {
-        warning() << "PendingChannel::channel called when not valid, returning 0";
-        return 0;
-    }
-
-    Channel* channel =
-        new Channel(connection(),
-                    mPriv->objectPath.path(),
-                    parent);
-    return channel;
-}
-
-void PendingChannel::onCallFinished(QDBusPendingCallWatcher* watcher)
-{
-    QDBusPendingReply<QDBusObjectPath> reply = *watcher;
-
-    debug() << "Received reply to RequestChannel";
-
-    if (!reply.isError()) {
-        debug() << " Success: object path" << reply.value().path();
-        mPriv->objectPath = reply.value();
-        setFinished();
-    } else {
-        debug().nospace() << " Failure: error " << reply.error().name() << ": " << reply.error().message();
-        setFinishedWithError(reply.error());
-    }
-
-    watcher->deleteLater();
-}
-
-} // Telepathy::Client
-} // Telepathy
diff --git a/TelepathyQt4/cli-pending-channel.h b/TelepathyQt4/cli-pending-channel.h
deleted file mode 100644
index 95d4243..0000000
--- a/TelepathyQt4/cli-pending-channel.h
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * This file is part of TelepathyQt4
- *
- * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
- * Copyright (C) 2008 Nokia Corporation
- *
- * 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.
- *
- * 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.
- *
- * 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 St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#ifndef _TelepathyQt4_cli_pending_channel_h_HEADER_GUARD_
-#define _TelepathyQt4_cli_pending_channel_h_HEADER_GUARD_
-
-/**
- * \addtogroup clientsideproxies Client-side proxies
- *
- * Proxy objects representing remote service objects accessed via D-Bus.
- *
- * In addition to providing direct access to methods, signals and properties
- * exported by the remote objects, some of these proxies offer features like
- * automatic inspection of remote object capabilities, property tracking,
- * backwards compatibility helpers for older services and other utilities.
- */
-
-/**
- * \defgroup clientconn Connection proxies
- * \ingroup clientsideproxies
- *
- * Proxy objects representing remote Telepathy Connections and their optional
- * interfaces.
- */
-
-namespace Telepathy
-{
-namespace Client
-{
-class PendingChannel;
-}
-}
-
-#include <TelepathyQt4/Constants>
-#include <TelepathyQt4/Types>
-#include <TelepathyQt4/Client/Connection>
-#include <TelepathyQt4/Client/PendingOperation>
-
-namespace Telepathy
-{
-namespace Client
-{
-
-/**
- * \class PendingChannel
- * \ingroup clientconn
- * \headerfile <TelepathyQt4/cli-pending-channel.h> <TelepathyQt4/Client/Connection>
- *
- * Class containing the parameters of and the reply to an asynchronous channel
- * request. Instances of this class cannot be constructed directly; the only way
- * to get one is to use Connection::requestChannel().
- */
-class PendingChannel : public PendingOperation
-{
-    Q_OBJECT
-
-public:
-    /**
-     * Class destructor.
-     */
-    ~PendingChannel();
-
-    /**
-     * Returns the Connection object through which the channel request was made.
-     *
-     * \return Pointer to the Connection.
-     */
-    Connection* connection() const;
-
-    /**
-     * Returns the channel type specified in the channel request.
-     *
-     * \return The D-Bus interface name of the interface specific to the
-     *         requested channel type.
-     */
-    const QString& channelType() const;
-
-    /**
-     * Returns the handle type specified in the channel request.
-     *
-     * \return The handle type, as specified in #HandleType.
-     */
-    uint handleType() const;
-
-    /**
-     * Returns the handle specified in the channel request.
-     *
-     * \return The handle.
-     */
-    uint handle() const;
-
-    /**
-     * Returns a newly constructed Channel high-level proxy object associated
-     * with the remote channel resulting from the channel request. If isValid()
-     * returns <code>false</code>, the request has not (at least yet) completed
-     * successfully, and 0 will be returned.
-     *
-     * \param parent Passed to the Channel constructor.
-     * \return Pointer to the new Channel object.
-     */
-    Channel* channel(QObject* parent = 0) const;
-
-private Q_SLOTS:
-    void onCallFinished(QDBusPendingCallWatcher* watcher);
-
-private:
-    friend class Connection;
-
-    PendingChannel(Connection* connection, const QString& type, uint handleType, uint handle);
-
-    struct Private;
-    friend struct Private;
-    Private *mPriv;
-};
-
-} // Telepathy::Client
-} // Telepathy
-
-#endif
diff --git a/TelepathyQt4/cli-pending-operation.cpp b/TelepathyQt4/cli-pending-operation.cpp
deleted file mode 100644
index 81085d3..0000000
--- a/TelepathyQt4/cli-pending-operation.cpp
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * This file is part of TelepathyQt4
- *
- * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
- * Copyright (C) 2008 Nokia Corporation
- *
- * 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.
- *
- * 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.
- *
- * 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 St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#include "cli-pending-operation.h"
-#include "cli-simple-pending-operations.h"
-
-#include <QTimer>
-
-#include <QDBusPendingCall>
-#include <QDBusPendingCallWatcher>
-
-#include "cli-pending-operation.moc.hpp"
-#include "cli-simple-pending-operations.moc.hpp"
-#include "debug-internal.hpp"
-
-namespace Telepathy
-{
-namespace Client
-{
-
-
-struct PendingOperation::Private
-{
-    inline Private()
-      : errorName(QString()),
-        errorMessage(QString()),
-        finished(false)
-    { }
-
-    QString errorName;
-    QString errorMessage;
-    bool finished;
-};
-
-
-PendingOperation::PendingOperation(QObject* parent)
-  : QObject(parent),
-    mPriv(new Private())
-{
-}
-
-
-PendingOperation::~PendingOperation()
-{
-    if (!mPriv->finished) {
-        warning() << this
-                << "still pending when it was deleted - finished will "
-                   "never be emitted";
-    }
-
-    delete mPriv;
-}
-
-
-void PendingOperation::emitFinished()
-{
-    Q_ASSERT(mPriv->finished);
-    emit finished(this);
-    deleteLater();
-}
-
-
-void PendingOperation::setFinished()
-{
-    if (mPriv->finished) {
-        if (mPriv->errorName.isEmpty())
-            warning() << this << "trying to finish with success, but already"
-              " failed with" << errorName() << ":" << errorMessage();
-        else
-            warning() << this << "trying to finish with success, but already"
-              " succeeded";
-        return;
-    }
-
-    mPriv->finished = true;
-    Q_ASSERT(isValid());
-    QTimer::singleShot(0, this, SLOT(emitFinished()));
-}
-
-
-void PendingOperation::setFinishedWithError(const QString& name,
-        const QString& message)
-{
-    if (mPriv->finished) {
-        if (mPriv->errorName.isEmpty())
-            warning() << this << "trying to fail with" << name <<
-              "but already failed with" << errorName() << ":" <<
-              errorMessage();
-        else
-            warning() << this << "trying to fail with" << name <<
-              "but already succeeded";
-        return;
-    }
-
-    if (name.isEmpty()) {
-        warning() << this << "should be given a non-empty error name";
-        mPriv->errorName = "org.freedesktop.Telepathy.Qt4.ErrorHandlingError";
-    }
-    else {
-        mPriv->errorName = name;
-    }
-
-    mPriv->errorMessage = message;
-    mPriv->finished = true;
-    Q_ASSERT(isError());
-    QTimer::singleShot(0, this, SLOT(emitFinished()));
-}
-
-
-void PendingOperation::setFinishedWithError(const QDBusError& error)
-{
-    setFinishedWithError(error.name(), error.message());
-}
-
-
-bool PendingOperation::isValid() const
-{
-    return (mPriv->finished && mPriv->errorName.isEmpty());
-}
-
-
-bool PendingOperation::isFinished() const
-{
-    return mPriv->finished;
-}
-
-
-bool PendingOperation::isError() const
-{
-    return (mPriv->finished && !mPriv->errorName.isEmpty());
-}
-
-
-QString PendingOperation::errorName() const
-{
-    return mPriv->errorName;
-}
-
-
-QString PendingOperation::errorMessage() const
-{
-    return mPriv->errorMessage;
-}
-
-
-PendingVoidMethodCall::PendingVoidMethodCall(QObject* proxy,
-    QDBusPendingCall call)
-  : PendingOperation(proxy),
-    mPriv(0)
-{
-    connect(new QDBusPendingCallWatcher(call),
-        SIGNAL(finished(QDBusPendingCallWatcher*)),
-        this,
-        SLOT(watcherFinished(QDBusPendingCallWatcher*)));
-}
-
-
-void PendingVoidMethodCall::watcherFinished(QDBusPendingCallWatcher* watcher)
-{
-    if (watcher->isError())
-    {
-        setFinishedWithError(watcher->error());
-    }
-    else
-    {
-        setFinished();
-    }
-}
-
-
-} // Telepathy::Client
-} // Telepathy
diff --git a/TelepathyQt4/cli-pending-operation.h b/TelepathyQt4/cli-pending-operation.h
deleted file mode 100644
index ada4824..0000000
--- a/TelepathyQt4/cli-pending-operation.h
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * This file is part of TelepathyQt4
- *
- * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
- * Copyright (C) 2008 Nokia Corporation
- *
- * 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.
- *
- * 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.
- *
- * 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 St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#ifndef _TelepathyQt4_cli_pending_operation_h_HEADER_GUARD_
-#define _TelepathyQt4_cli_pending_operation_h_HEADER_GUARD_
-
-#include <QObject>
-
-class QDBusError;
-class QDBusPendingCall;
-class QDBusPendingCallWatcher;
-
-namespace Telepathy
-{
-namespace Client
-{
-
-/**
- * Abstract base class for pending asynchronous operations.
- *
- * This class represents an incomplete asynchronous operation, such as a
- * D-Bus method call. When the operation has finished, it emits
- * #finished. The slot or slots connected to the #finished() signal may obtain
- * additional information from the %PendingOperation.
- *
- * In simple cases, like a D-Bus method with no 'out' arguments or for which
- * all 'out' arguments are to be ignored (so the possible results are
- * success with no extra information, or failure with an error code), the
- * trivial subclass %PendingVoidMethodCall can be used.
- *
- * For pending operations that produce a result, another subclass of
- * %PendingOperation can be used, with additional methods that provide that
- * result to the library user.
- *
- * After #finished() is emitted, the %PendingOperation is automatically
- * deleted using deleteLater(), so library users must not explicitly
- * delete this object.
- *
- * The design is loosely based on KDE's KJob.
- */
-class PendingOperation : public QObject
-{
-    Q_OBJECT
-
-public:
-    virtual ~PendingOperation();
-
-    /**
-     * Returns whether or not the request has finished processing. #finished()
-     * is emitted when this changes from <code>false</code> to
-     * <code>true</code>.
-     *
-     * Equivalent to <code>(isValid() || isError())</code>.
-     *
-     * \sa finished()
-     *
-     * \return <code>true</code> if the request has finished
-     */
-    bool isFinished() const;
-
-    /**
-     * Returns whether or not the request completed successfully. If the
-     * request has not yet finished processing (isFinished() returns
-     * <code>false</code>), this cannot yet be known, and <code>false</code>
-     * will be returned.
-     *
-     * Equivalent to <code>(isFinished() && !isError())</code>.
-     *
-     * \return <code>true</code> iff the request has finished processing AND
-     *         has completed successfully.
-     */
-    bool isValid() const;
-
-    /**
-     * Returns whether or not the request resulted in an error. If the
-     * request has not yet finished processing (isFinished() returns
-     * <code>false</code>), this cannot yet be known, and <code>false</code>
-     * will be returned.
-     *
-     * Equivalent to <code>(isFinished() && !isValid())</code>.
-     *
-     * \return <code>true</code> iff the request has finished processing AND
-     *         has resulted in an error.
-     */
-    bool isError() const;
-
-    /**
-     * If #isError() would return true, returns the D-Bus error with which
-     * the operation failed. If the operation succeeded or has not yet
-     * finished, returns an empty string.
-     *
-     * \return a D-Bus error name or an empty string
-     */
-    QString errorName() const;
-
-    /**
-     * If isError() would return true, returns a debugging message associated
-     * with the error, which may be an empty string. Otherwise, return an
-     * empty string.
-     *
-     * \return a debugging message or an empty string
-     */
-    QString errorMessage() const;
-
-Q_SIGNALS:
-    /**
-     * Emitted when the pending operation finishes, i.e. when #isFinished()
-     * changes from <code>false</code> to <code>true</code>.
-     *
-     * \param operation This operation object, from which further information
-     *    may be obtained
-     */
-    void finished(Telepathy::Client::PendingOperation* operation);
-
-protected:
-    /**
-     * Protected constructor. Only subclasses of this class may be constructed
-     *
-     * \param parent The object on which this pending operation takes place
-     */
-    PendingOperation(QObject* parent);
-
-    /**
-     * Record that this pending operation has finished successfully, and
-     * emit the #finished() signal next time the event loop runs.
-     */
-    void setFinished();
-
-    /**
-     * Record that this pending operation has finished with an error, and
-     * emit the #finished() signal next time the event loop runs.
-     *
-     * \param name A D-Bus error name, which must be non-empty
-     * \param message A debugging message
-     */
-    void setFinishedWithError(const QString& name, const QString& message);
-
-    /**
-     * Record that this pending operation has finished with an error, and
-     * emit the #finished() signal next time the event loop runs.
-     *
-     * \param error A QtDBus error
-     */
-    void setFinishedWithError(const QDBusError& error);
-
-private Q_SLOTS:
-    void emitFinished();
-
-private:
-    struct Private;
-    Private *mPriv;
-};
-
-
-} // Telepathy::Client
-} // Telepathy
-
-#endif
diff --git a/TelepathyQt4/cli-properties.cpp b/TelepathyQt4/cli-properties.cpp
deleted file mode 100644
index f8f9065..0000000
--- a/TelepathyQt4/cli-properties.cpp
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * This file is part of TelepathyQt4
- *
- * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
- * Copyright (C) 2008 Nokia Corporation
- *
- * 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.
- *
- * 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.
- *
- * 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 St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#include <TelepathyQt4/_gen/cli-properties-body.hpp>
-#include <TelepathyQt4/_gen/cli-properties.moc.hpp>
diff --git a/TelepathyQt4/cli-properties.h b/TelepathyQt4/cli-properties.h
deleted file mode 100644
index 23c85ac..0000000
--- a/TelepathyQt4/cli-properties.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * This file is part of TelepathyQt4
- *
- * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
- * Copyright (C) 2008 Nokia Corporation
- *
- * 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.
- *
- * 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.
- *
- * 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 St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#ifndef _TelepathyQt4_cli_properties_h_HEADER_GUARD_
-#define _TelepathyQt4_cli_properties_h_HEADER_GUARD_
-
-/**
- * \addtogroup clientsideproxies Client-side proxies
- *
- * Proxy objects representing remote service objects accessed via D-Bus.
- *
- * In addition to providing direct access to methods, signals and properties
- * exported by the remote objects, some of these proxies offer features like
- * automatic inspection of remote object capabilities, property tracking,
- * backwards compatibility helpers for older services and other utilities.
- */
-
-/**
- * \defgroup clientprops Telepathy Properties proxy
- * \ingroup clientsideproxies
- *
- * Proxy object representing the Telepathy Properties interface on remote
- * objects.
- */
-
-#include <TelepathyQt4/_gen/cli-properties.h>
-
-#endif
diff --git a/TelepathyQt4/cli-simple-pending-operations.h b/TelepathyQt4/cli-simple-pending-operations.h
deleted file mode 100644
index bd1f5e2..0000000
--- a/TelepathyQt4/cli-simple-pending-operations.h
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * This file is part of TelepathyQt4
- *
- * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
- * Copyright (C) 2008 Nokia Corporation
- *
- * 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.
- *
- * 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.
- *
- * 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 St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#ifndef _TelepathyQt4_cli_pending_operations_h_HEADER_GUARD_
-#define _TelepathyQt4_cli_pending_operations_h_HEADER_GUARD_
-
-#include <QObject>
-
-#include <TelepathyQt4/Client/PendingOperation>
-
-namespace Telepathy
-{
-namespace Client
-{
-
-
-/**
- * A %PendingOperation that is always successful.
- */
-class PendingSuccess : public PendingOperation
-{
-    Q_OBJECT
-
-public:
-    PendingSuccess(QObject* parent)
-        : PendingOperation(parent)
-    {
-        setFinished();
-    }
-};
-
-
-/**
- * A %PendingOperation that always fails with the error passed to the
- * constructor.
- */
-class PendingFailure : public PendingOperation
-{
-    Q_OBJECT
-
-public:
-    PendingFailure(QObject* parent, const QString& name,
-            const QString& message)
-        : PendingOperation(parent)
-    {
-        setFinishedWithError(name, message);
-    }
-
-    PendingFailure(QObject* parent, const QDBusError& error)
-        : PendingOperation(parent)
-    {
-        setFinishedWithError(error);
-    }
-};
-
-
-/**
- * Generic subclass of %PendingOperation representing a pending D-Bus method
- * call that does not return anything (or returns a result that is not
- * interesting).
- *
- * Objects of this class indicate the success or failure of the method call,
- * but if the method call succeeds, no additional information is available.
- */
-class PendingVoidMethodCall : public PendingOperation
-{
-    Q_OBJECT
-
-public:
-    /**
-     * Constructor.
-     *
-     * \param parent The object on which this pending operation takes place
-     * \param call A pending call as returned by the auto-generated low level
-     *             Telepathy API; if the method returns anything, the return
-     *             value(s) will be ignored
-     */
-    PendingVoidMethodCall(QObject* parent, QDBusPendingCall call);
-
-private Q_SLOTS:
-    void watcherFinished(QDBusPendingCallWatcher*);
-
-private:
-    // just ABI padding at the moment
-    struct Private;
-    Private *mPriv;
-};
-
-
-} // Telepathy::Client
-} // Telepathy
-
-#endif
diff --git a/tests/prototype/prototype.cpp b/tests/prototype/prototype.cpp
index 321a9cf..03a5379 100644
--- a/tests/prototype/prototype.cpp
+++ b/tests/prototype/prototype.cpp
@@ -10,6 +10,7 @@
 
 #include <QtTest/QSignalSpy>
 
+#include <TelepathyQt4/Client/Account>
 #include <TelepathyQt4/Client/AccountManager>
 #include <TelepathyQt4/Client/ConnectionManager>
 #include <TelepathyQt4/Client/Connection>
-- 
1.5.6.5




More information about the Telepathy-commits mailing list