diff --git a/libpurple/protocols/ircv3/purpleircv3connection.h b/libpurple/protocols/ircv3/purpleircv3connection.h
--- a/libpurple/protocols/ircv3/purpleircv3connection.h
+++ b/libpurple/protocols/ircv3/purpleircv3connection.h
@@ -31,22 +31,14 @@
 
 #define PURPLE_IRCV3_TYPE_CONNECTION (purple_ircv3_connection_get_type())
 G_DECLARE_FINAL_TYPE(PurpleIRCv3Connection, purple_ircv3_connection,
-                     PURPLE_IRCV3, CONNECTION, GObject)
+                     PURPLE_IRCV3, CONNECTION, PurpleConnection)
 
 G_GNUC_INTERNAL void purple_ircv3_connection_register(GPluginNativePlugin *plugin);
 
-G_GNUC_INTERNAL PurpleIRCv3Connection *purple_ircv3_connection_new(PurpleAccount *account);
-
 G_GNUC_INTERNAL PurpleAccount *purple_ircv3_connection_get_account(PurpleIRCv3Connection *connection);
 
 G_GNUC_INTERNAL GCancellable *purple_ircv3_connection_get_cancellable(PurpleIRCv3Connection *connection);
 
-G_GNUC_INTERNAL gboolean purple_ircv3_connection_valid(PurpleIRCv3Connection *connection, GError **error);
-
-G_GNUC_INTERNAL void purple_ircv3_connection_connect(PurpleIRCv3Connection *connection);
-
-G_GNUC_INTERNAL void purple_ircv3_connection_close(PurpleIRCv3Connection *connection);
-
 G_GNUC_INTERNAL void purple_ircv3_connection_writef(PurpleIRCv3Connection *connection, const char *format, ...) G_GNUC_PRINTF(2, 3);
 
 /**
# HG changeset patch
# Node ID db1d8506ffb1
# Parent  7bd5bff547b4
diff --git a/libpurple/protocols/ircv3/purpleircv3connection.c b/libpurple/protocols/ircv3/purpleircv3connection.c
--- a/libpurple/protocols/ircv3/purpleircv3connection.c
+++ b/libpurple/protocols/ircv3/purpleircv3connection.c
@@ -25,7 +25,6 @@
 
 enum {
 	PROP_0,
-	PROP_ACCOUNT,
 	PROP_CANCELLABLE,
 	PROP_CAPABILITIES,
 	N_PROPERTIES,
@@ -33,10 +32,7 @@
 static GParamSpec *properties[N_PROPERTIES] = {NULL, };
 
 struct _PurpleIRCv3Connection {
-	GObject parent;
-
-	GError *validate_error;
-	PurpleAccount *account;
+	PurpleConnection parent;
 
 	GSocketConnection *connection;
 	GCancellable *cancellable;
@@ -52,42 +48,32 @@
 };
 
 G_DEFINE_DYNAMIC_TYPE(PurpleIRCv3Connection, purple_ircv3_connection,
-                      G_TYPE_OBJECT)
+                      PURPLE_TYPE_CONNECTION)
 
 /******************************************************************************
  * Helpers
  *****************************************************************************/
 static void
-purple_ircv3_connection_set_account(PurpleIRCv3Connection *connection,
-                                    PurpleAccount *account)
-{
-	g_return_if_fail(PURPLE_IRCV3_IS_CONNECTION(connection));
-
-	if(g_set_object(&connection->account, account)) {
-		g_object_notify_by_pspec(G_OBJECT(connection),
-		                         properties[PROP_ACCOUNT]);
-	}
-}
-
-static void
 purple_ircv3_connection_send_user_command(PurpleIRCv3Connection *connection) {
-	PurpleConnection *purple_connection = NULL;
+	PurpleAccount *account = NULL;
 	const char *identname = NULL;
 	const char *nickname = NULL;
 	const char *realname = NULL;
 
-	purple_connection = purple_account_get_connection(connection->account);
-	nickname = purple_connection_get_display_name(purple_connection);
+	nickname =
+		purple_connection_get_display_name(PURPLE_CONNECTION(connection));
+
+	account = purple_connection_get_account(PURPLE_CONNECTION(connection));
 
 	/* The stored value could be an empty string, so pass a default of empty
 	 * string and then if it was empty, set our correct fallback.
 	 */
-	identname = purple_account_get_string(connection->account, "ident", "");
+	identname = purple_account_get_string(account, "ident", "");
 	if(identname == NULL || *identname == '\0') {
 		identname = nickname;
 	}
 
-	realname = purple_account_get_string(connection->account, "real-name", "");
+	realname = purple_account_get_string(account, "real-name", "");
 	if(realname == NULL || *realname == '\0') {
 		realname = nickname;
 	}
@@ -98,12 +84,10 @@
 
 static void
 purple_ircv3_connection_send_nick_command(PurpleIRCv3Connection *connection) {
-	PurpleConnection *purple_connection = NULL;
 	const char *nickname = NULL;
 
-	purple_connection = purple_account_get_connection(connection->account);
-
-	nickname = purple_connection_get_display_name(purple_connection);
+	nickname =
+		purple_connection_get_display_name(PURPLE_CONNECTION(connection));
 
 	purple_ircv3_connection_writef(connection, "NICK %s", nickname);
 }
@@ -115,8 +99,7 @@
 purple_ircv3_connection_read_cb(GObject *source, GAsyncResult *result,
                                 gpointer data)
 {
-	PurpleIRCv3Connection *connection = NULL;
-	PurpleConnection *purple_connection = data;
+	PurpleIRCv3Connection *connection = data;
 	GDataInputStream *istream = G_DATA_INPUT_STREAM(source);
 	GError *error = NULL;
 	gchar *line = NULL;
@@ -125,24 +108,24 @@
 	line = g_data_input_stream_read_line_finish(istream, result, &length,
 	                                            &error);
 	if(line == NULL || error != NULL) {
-		if(error == NULL) {
-			g_set_error_literal(&error, PURPLE_CONNECTION_ERROR,
-			                    PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
-			                    _("Server closed the connection"));
-		} else {
-			g_prefix_error(&error, "%s", _("Lost connection with server: "));
+		if(PURPLE_IS_CONNECTION(connection)) {
+			if(error == NULL) {
+				g_set_error_literal(&error, PURPLE_CONNECTION_ERROR,
+				                    PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
+				                    _("Server closed the connection"));
+			} else {
+				g_prefix_error(&error, "%s", _("Lost connection with server: "));
+			}
+
+			purple_connection_take_error(PURPLE_CONNECTION(connection), error);
 		}
 
-		purple_connection_take_error(purple_connection, error);
-
 		/* In the off chance that line was returned, make sure we free it. */
 		g_free(line);
 
 		return;
 	}
 
-	connection = g_object_get_data(G_OBJECT(purple_connection),
-	                               PURPLE_IRCV3_CONNECTION_KEY);
 	purple_ircv3_parser_parse(connection->parser, line, &error, connection);
 
 	g_free(line);
@@ -152,7 +135,7 @@
 	                                    G_PRIORITY_DEFAULT,
 	                                    connection->cancellable,
 	                                    purple_ircv3_connection_read_cb,
-	                                    purple_connection);
+	                                    connection);
 }
 
 static void
@@ -168,14 +151,11 @@
 	                                                        &error);
 
 	if(!success) {
-		PurpleConnection *purple_connection = NULL;
-		purple_connection = purple_account_get_connection(connection->account);
-
 		purple_queued_output_stream_clear_queue(stream);
 
 		g_prefix_error(&error, "%s", _("Lost connection with server: "));
 
-		purple_connection_take_error(purple_connection, error);
+		purple_connection_take_error(PURPLE_CONNECTION(connection), error);
 
 		return;
 	}
@@ -185,8 +165,7 @@
 purple_ircv3_connection_connected_cb(GObject *source, GAsyncResult *result,
                                      gpointer data)
 {
-	PurpleIRCv3Connection *connection = NULL;
-	PurpleConnection *purple_connection = data;
+	PurpleIRCv3Connection *connection = data;
 	GError *error = NULL;
 	GInputStream *istream = NULL;
 	GOutputStream *ostream = NULL;
@@ -198,15 +177,12 @@
 	if(conn == NULL || error != NULL) {
 		g_prefix_error(&error, "%s", _("Unable to connect: "));
 
-		purple_connection_take_error(purple_connection, error);
+		purple_connection_take_error(PURPLE_CONNECTION(connection), error);
 
 		return;
 	}
 
-	connection = g_object_get_data(G_OBJECT(purple_connection),
-	                               PURPLE_IRCV3_CONNECTION_KEY);
-
-	purple_connection_set_state(purple_connection,
+	purple_connection_set_state(PURPLE_CONNECTION(connection),
 	                            PURPLE_CONNECTION_STATE_CONNECTED);
 
 	g_message("Successfully connected to %s", connection->server_name);
@@ -231,7 +207,7 @@
 	                                    G_PRIORITY_DEFAULT,
 	                                    connection->cancellable,
 	                                    purple_ircv3_connection_read_cb,
-	                                    purple_connection);
+	                                    connection);
 
 	/* Send our registration commands. */
 	purple_ircv3_connection_writef(connection, "CAP LS %s",
@@ -241,6 +217,89 @@
 }
 
 /******************************************************************************
+ * PurpleConnection Implementation
+ *****************************************************************************/
+static gboolean
+purple_ircv3_connection_connect(PurpleConnection *purple_connection,
+                                GError **error)
+{
+	PurpleIRCv3Connection *connection = NULL;
+	PurpleAccount *account = NULL;
+	GSocketClient *client = NULL;
+	gint default_port = PURPLE_IRCV3_DEFAULT_TLS_PORT;
+	gint port = 0;
+	gboolean use_tls = TRUE;
+
+	g_return_val_if_fail(PURPLE_IRCV3_IS_CONNECTION(purple_connection), FALSE);
+
+	connection = PURPLE_IRCV3_CONNECTION(purple_connection);
+	account = purple_connection_get_account(purple_connection);
+
+	client = purple_gio_socket_client_new(account, error);
+	if(!G_IS_SOCKET_CLIENT(client)) {
+		if(error != NULL && *error != NULL) {
+			purple_connection_take_error(purple_connection, *error);
+		}
+
+		return FALSE;
+	}
+
+	/* Turn on TLS if requested. */
+	use_tls = purple_account_get_bool(account, "use-tls", TRUE);
+	g_socket_client_set_tls(client, use_tls);
+
+	/* If TLS is not being used, set the default port to the plain port. */
+	if(!use_tls) {
+		default_port = PURPLE_IRCV3_DEFAULT_PLAIN_PORT;
+	}
+	port = purple_account_get_int(account, "port", default_port);
+
+	/* Finally start the async connection. */
+	g_socket_client_connect_to_host_async(client, connection->server_name,
+	                                      port, connection->cancellable,
+	                                      purple_ircv3_connection_connected_cb,
+	                                      connection);
+
+	g_clear_object(&client);
+
+	return TRUE;
+}
+
+static gboolean
+purple_ircv3_connection_disconnect(PurpleConnection *purple_connection,
+                                   GError **error)
+{
+	PurpleIRCv3Connection *connection = NULL;
+
+	g_return_val_if_fail(PURPLE_IRCV3_IS_CONNECTION(purple_connection), FALSE);
+
+	connection = PURPLE_IRCV3_CONNECTION(purple_connection);
+
+	/* TODO: send QUIT command. */
+
+	/* Cancel the cancellable to tell everyone we're shutting down. */
+	if(G_IS_CANCELLABLE(connection->cancellable)) {
+		g_cancellable_cancel(connection->cancellable);
+
+		g_clear_object(&connection->cancellable);
+	}
+
+	if(G_IS_SOCKET_CONNECTION(connection->connection)) {
+		GInputStream *istream = G_INPUT_STREAM(connection->input);
+		GOutputStream *ostream = G_OUTPUT_STREAM(connection->output);
+
+		purple_gio_graceful_close(G_IO_STREAM(connection->connection),
+		                          istream, ostream);
+	}
+
+	g_clear_object(&connection->input);
+	g_clear_object(&connection->output);
+	g_clear_object(&connection->connection);
+
+	return TRUE;
+}
+
+/******************************************************************************
  * GObject Implementation
  *****************************************************************************/
 static void
@@ -250,10 +309,6 @@
 	PurpleIRCv3Connection *connection = PURPLE_IRCV3_CONNECTION(obj);
 
 	switch(param_id) {
-		case PROP_ACCOUNT:
-			g_value_set_object(value,
-			                   purple_ircv3_connection_get_account(connection));
-			break;
 		case PROP_CANCELLABLE:
 			g_value_set_object(value,
 			                   purple_ircv3_connection_get_cancellable(connection));
@@ -272,13 +327,9 @@
 purple_ircv3_connection_set_property(GObject *obj, guint param_id,
                                      const GValue *value, GParamSpec *pspec)
 {
-	PurpleIRCv3Connection *connection = PURPLE_IRCV3_CONNECTION(obj);
+	// PurpleIRCv3Connection *connection = PURPLE_IRCV3_CONNECTION(obj);
 
 	switch(param_id) {
-		case PROP_ACCOUNT:
-			purple_ircv3_connection_set_account(connection,
-			                                    g_value_get_object(value));
-			break;
 		default:
 			G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
 			break;
@@ -289,7 +340,6 @@
 purple_ircv3_connection_dispose(GObject *obj) {
 	PurpleIRCv3Connection *connection = PURPLE_IRCV3_CONNECTION(obj);
 
-	g_clear_object(&connection->account);
 	g_clear_object(&connection->cancellable);
 
 	g_clear_object(&connection->input);
@@ -305,7 +355,6 @@
 purple_ircv3_connection_finalize(GObject *obj) {
 	PurpleIRCv3Connection *connection = PURPLE_IRCV3_CONNECTION(obj);
 
-	g_clear_error(&connection->validate_error);
 	g_clear_pointer(&connection->server_name, g_free);
 
 	g_clear_pointer(&connection->capabilities, g_free);
@@ -316,30 +365,19 @@
 static void
 purple_ircv3_connection_constructed(GObject *obj) {
 	PurpleIRCv3Connection *connection = PURPLE_IRCV3_CONNECTION(obj);
-	PurpleConnection *purple_connection = NULL;
+	PurpleAccount *account = NULL;
 	gchar **userparts = NULL;
 	const gchar *username = NULL;
 
 	G_OBJECT_CLASS(purple_ircv3_connection_parent_class)->constructed(obj);
 
-	purple_connection = purple_account_get_connection(connection->account);
-
-	/* Make sure the username (which includes the servername via usersplits),
-	 * does not contain any whitespace.
-	 */
-	username = purple_account_get_username(connection->account);
-	if(strpbrk(username, " \t\v\r\n") != NULL) {
-		g_set_error(&connection->validate_error,
-		            PURPLE_CONNECTION_ERROR,
-		            PURPLE_CONNECTION_ERROR_INVALID_SETTINGS,
-		            _("IRC nick and server may not contain whitespace"));
-
-		return;
-	}
+	account = purple_connection_get_account(PURPLE_CONNECTION(connection));
 
 	/* Split the username into nick and server and store the values. */
+	username = purple_account_get_username(account);
 	userparts = g_strsplit(username, "@", 2);
-	purple_connection_set_display_name(purple_connection, userparts[0]);
+	purple_connection_set_display_name(PURPLE_CONNECTION(connection),
+	                                   userparts[0]);
 	connection->server_name = g_strdup(userparts[1]);
 	g_strfreev(userparts);
 
@@ -358,6 +396,7 @@
 static void
 purple_ircv3_connection_class_init(PurpleIRCv3ConnectionClass *klass) {
 	GObjectClass *obj_class = G_OBJECT_CLASS(klass);
+	PurpleConnectionClass *connection_class = PURPLE_CONNECTION_CLASS(klass);
 
 	obj_class->get_property = purple_ircv3_connection_get_property;
 	obj_class->set_property = purple_ircv3_connection_set_property;
@@ -365,18 +404,8 @@
 	obj_class->dispose = purple_ircv3_connection_dispose;
 	obj_class->finalize = purple_ircv3_connection_finalize;
 
-	/**
-	 * PurpleIRCv3Connection:account:
-	 *
-	 * The [class@Purple.Account] that this connection is for.
-	 *
-	 * Since: 3.0.0
-	 */
-	properties[PROP_ACCOUNT] = g_param_spec_object(
-		"account", "account",
-		"The account for this connection",
-		PURPLE_TYPE_ACCOUNT,
-		G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
+	connection_class->connect = purple_ircv3_connection_connect;
+	connection_class->disconnect = purple_ircv3_connection_disconnect;
 
 	/**
 	 * PurpleIRCv3Connection:cancellable:
@@ -418,21 +447,6 @@
 	purple_ircv3_connection_register_type(G_TYPE_MODULE(plugin));
 }
 
-PurpleIRCv3Connection *
-purple_ircv3_connection_new(PurpleAccount *account) {
-	return g_object_new(
-		PURPLE_IRCV3_TYPE_CONNECTION,
-		"account", account,
-		NULL);
-}
-
-PurpleAccount *
-purple_ircv3_connection_get_account(PurpleIRCv3Connection *connection) {
-	g_return_val_if_fail(PURPLE_IRCV3_IS_CONNECTION(connection), NULL);
-
-	return connection->account;
-}
-
 GCancellable *
 purple_ircv3_connection_get_cancellable(PurpleIRCv3Connection *connection) {
 	g_return_val_if_fail(PURPLE_IRCV3_IS_CONNECTION(connection), NULL);
@@ -440,87 +454,6 @@
 	return connection->cancellable;
 }
 
-gboolean
-purple_ircv3_connection_valid(PurpleIRCv3Connection *connection,
-                              GError **error)
-{
-	g_return_val_if_fail(PURPLE_IRCV3_IS_CONNECTION(connection), FALSE);
-
-	if(connection->validate_error != NULL) {
-		g_propagate_error(error, connection->validate_error);
-		connection->validate_error = NULL;
-
-		return FALSE;
-	}
-
-	return TRUE;
-}
-
-void
-purple_ircv3_connection_connect(PurpleIRCv3Connection *connection) {
-	PurpleConnection *purple_connection = NULL;
-	GError *error = NULL;
-	GSocketClient *client = NULL;
-	gint default_port = PURPLE_IRCV3_DEFAULT_TLS_PORT;
-	gint port = 0;
-	gboolean use_tls = TRUE;
-
-	g_return_if_fail(PURPLE_IRCV3_IS_CONNECTION(connection));
-	g_return_if_fail(connection->connection == NULL);
-
-	purple_connection = purple_account_get_connection(connection->account);
-	client = purple_gio_socket_client_new(connection->account, &error);
-	if(!G_IS_SOCKET_CLIENT(client)) {
-		purple_connection_take_error(purple_connection, error);
-
-		return;
-	}
-
-	/* Turn on TLS if requested. */
-	use_tls = purple_account_get_bool(connection->account, "use-tls", TRUE);
-	g_socket_client_set_tls(client, use_tls);
-
-	/* If TLS is not being used, set the default port to the plain port. */
-	if(!use_tls) {
-		default_port = PURPLE_IRCV3_DEFAULT_PLAIN_PORT;
-	}
-	port = purple_account_get_int(connection->account, "port", default_port);
-
-	/* Finally start the async connection. */
-	g_socket_client_connect_to_host_async(client, connection->server_name,
-	                                      port, connection->cancellable,
-	                                      purple_ircv3_connection_connected_cb,
-	                                      purple_connection);
-
-	g_clear_object(&client);
-}
-
-void
-purple_ircv3_connection_close(PurpleIRCv3Connection *connection) {
-	g_return_if_fail(PURPLE_IRCV3_IS_CONNECTION(connection));
-
-	/* TODO: send QUIT command. */
-
-	/* Cancel the cancellable to tell everyone we're shutting down. */
-	if(G_IS_CANCELLABLE(connection->cancellable)) {
-		g_cancellable_cancel(connection->cancellable);
-
-		g_clear_object(&connection->cancellable);
-	}
-
-	if(G_IS_SOCKET_CONNECTION(connection->connection)) {
-		GInputStream *istream = G_INPUT_STREAM(connection->input);
-		GOutputStream *ostream = G_OUTPUT_STREAM(connection->output);
-
-		purple_gio_graceful_close(G_IO_STREAM(connection->connection),
-		                          istream, ostream);
-	}
-
-	g_clear_object(&connection->input);
-	g_clear_object(&connection->output);
-	g_clear_object(&connection->connection);
-}
-
 void
 purple_ircv3_connection_writef(PurpleIRCv3Connection *connection,
                                const char *format, ...)
diff --git a/libpurple/protocols/ircv3/purpleircv3core.h b/libpurple/protocols/ircv3/purpleircv3core.h
--- a/libpurple/protocols/ircv3/purpleircv3core.h
+++ b/libpurple/protocols/ircv3/purpleircv3core.h
@@ -27,8 +27,6 @@
 
 #define PURPLE_IRCV3_DOMAIN (g_quark_from_static_string("ircv3-plugin"))
 
-#define PURPLE_IRCV3_CONNECTION_KEY "ircv3-connection"
-
 #define PURPLE_IRCV3_CONNECTION_CAP_VERSION "302"
 
 #endif /* PURPLE_IRCV3_CORE_H */
diff --git a/libpurple/protocols/ircv3/purpleircv3messagehandlers.c b/libpurple/protocols/ircv3/purpleircv3messagehandlers.c
--- a/libpurple/protocols/ircv3/purpleircv3messagehandlers.c
+++ b/libpurple/protocols/ircv3/purpleircv3messagehandlers.c
@@ -160,7 +160,7 @@
 		return FALSE;
 	}
 
-	account = purple_ircv3_connection_get_account(connection);
+	account = purple_connection_get_account(PURPLE_CONNECTION(connection));
 
 	contact_manager = purple_contact_manager_get_default();
 	contact = purple_contact_manager_find_with_username(contact_manager,
diff --git a/libpurple/protocols/ircv3/purpleircv3protocol.c b/libpurple/protocols/ircv3/purpleircv3protocol.c
--- a/libpurple/protocols/ircv3/purpleircv3protocol.c
+++ b/libpurple/protocols/ircv3/purpleircv3protocol.c
@@ -23,10 +23,6 @@
 #include "purpleircv3connection.h"
 #include "purpleircv3core.h"
 
-typedef struct {
-	gboolean dummy;
-} PurpleIRCv3ProtocolPrivate;
-
 /******************************************************************************
  * PurpleProtocol Implementation
  *****************************************************************************/
@@ -84,44 +80,36 @@
 	return options;
 }
 
-static void
-purple_ircv3_protocol_login(G_GNUC_UNUSED PurpleProtocol *protocol,
-                            PurpleAccount *account)
+static PurpleConnection *
+purple_ircv3_protocol_create_connection(PurpleProtocol *protocol,
+                                        PurpleAccount *account,
+                                        const char *password,
+                                        GError **error)
 {
-	PurpleIRCv3Connection *connection = NULL;
-	PurpleConnection *purple_connection = NULL;
-	GError *error = NULL;
+	const char *username = NULL;
+
+	g_return_val_if_fail(PURPLE_IS_PROTOCOL(protocol), NULL);
+	g_return_val_if_fail(PURPLE_IS_ACCOUNT(account), NULL);
 
-	purple_connection = purple_account_get_connection(account);
+	/* Make sure the username (which includes the servername via usersplits),
+	 * does not contain any whitespace.
+	 */
+	username = purple_account_get_username(account);
+	if(strpbrk(username, " \t\v\r\n") != NULL) {
+		g_set_error(error,
+		            PURPLE_CONNECTION_ERROR,
+		            PURPLE_CONNECTION_ERROR_INVALID_SETTINGS,
+		            _("IRC nick and server may not contain whitespace"));
 
-	connection = purple_ircv3_connection_new(account);
-	if(!purple_ircv3_connection_valid(connection, &error)) {
-		purple_connection_take_error(purple_connection, error);
-
-		return;
+		return NULL;
 	}
 
-	g_object_set_data_full(G_OBJECT(purple_connection),
-	                       PURPLE_IRCV3_CONNECTION_KEY,
-	                       connection, g_object_unref);
-
-	purple_ircv3_connection_connect(connection);
-}
-
-static void
-purple_ircv3_protocol_close(G_GNUC_UNUSED PurpleProtocol *protocol,
-                            PurpleConnection *purple_connection)
-{
-	PurpleIRCv3Connection *connection = NULL;
-
-	connection = g_object_get_data(G_OBJECT(purple_connection),
-	                               PURPLE_IRCV3_CONNECTION_KEY);
-
-	purple_ircv3_connection_close(connection);
-
-	/* Set our connection data to NULL which will remove the last reference. */
-	g_object_set_data(G_OBJECT(purple_connection), PURPLE_IRCV3_CONNECTION_KEY,
-	                  NULL);
+	return g_object_new(
+		PURPLE_IRCV3_TYPE_CONNECTION,
+		"protocol", protocol,
+		"account", account,
+		"password", password,
+		NULL);
 }
 
 static GList *
@@ -149,9 +137,8 @@
 /******************************************************************************
  * GObject Implementation
  *****************************************************************************/
-G_DEFINE_DYNAMIC_TYPE_EXTENDED(
-	PurpleIRCv3Protocol, purple_ircv3_protocol, PURPLE_TYPE_PROTOCOL, 0,
-	G_ADD_PRIVATE_DYNAMIC(PurpleIRCv3Protocol))
+G_DEFINE_DYNAMIC_TYPE(PurpleIRCv3Protocol, purple_ircv3_protocol,
+                      PURPLE_TYPE_PROTOCOL)
 
 static void
 purple_ircv3_protocol_init(PurpleIRCv3Protocol *protocol) {
@@ -168,8 +155,8 @@
 	protocol_class->get_user_splits = purple_ircv3_protocol_get_user_splits;
 	protocol_class->get_account_options =
 		purple_ircv3_protocol_get_account_options;
-	protocol_class->login = purple_ircv3_protocol_login;
-	protocol_class->close = purple_ircv3_protocol_close;
+	protocol_class->create_connection =
+		purple_ircv3_protocol_create_connection;
 	protocol_class->status_types = purple_ircv3_protocol_status_types;
 }
 
