Index: irc_im.c
===================================================================
--- irc_im.c	(revision 14f912d4c1e818d39234c874036e4fe60227d1dc)
+++ irc_im.c	(revision a42fda42abad6af64ac9a905856ee9a3095954cd)
@@ -342,5 +342,5 @@
 }
 
-static gboolean bee_irc_user_nick_update(irc_user_t *iu);
+static gboolean bee_irc_user_nick_update(irc_user_t *iu, gboolean offline_only);
 
 static gboolean bee_irc_user_fullname(bee_t *bee, bee_user_t *bu)
@@ -370,5 +370,5 @@
 	}
 
-	bee_irc_user_nick_update(iu);
+	bee_irc_user_nick_update(iu, TRUE);
 
 	return TRUE;
@@ -377,5 +377,12 @@
 static gboolean bee_irc_user_nick_hint(bee_t *bee, bee_user_t *bu, const char *hint)
 {
-	bee_irc_user_nick_update((irc_user_t *) bu->ui_data);
+	bee_irc_user_nick_update((irc_user_t *) bu->ui_data, TRUE);
+
+	return TRUE;
+}
+
+static gboolean bee_irc_user_nick_change(bee_t *bee, bee_user_t *bu, const char *nick)
+{
+	bee_irc_user_nick_update((irc_user_t *) bu->ui_data, FALSE);
 
 	return TRUE;
@@ -386,28 +393,17 @@
 	irc_user_t *iu = (irc_user_t *) bu->ui_data;
 	irc_t *irc = (irc_t *) bee->ui_data;
-	bee_user_flags_t online;
-
-	/* Take the user offline temporarily so we can change the nick (if necessary). */
-	if ((online = bu->flags & BEE_USER_ONLINE)) {
-		bu->flags &= ~BEE_USER_ONLINE;
-	}
 
 	bee_irc_channel_update(irc, NULL, iu);
-	bee_irc_user_nick_update(iu);
-
-	if (online) {
-		bu->flags |= online;
-		bee_irc_channel_update(irc, NULL, iu);
-	}
-
-	return TRUE;
-}
-
-static gboolean bee_irc_user_nick_update(irc_user_t *iu)
+	bee_irc_user_nick_update(iu, FALSE);
+
+	return TRUE;
+}
+
+static gboolean bee_irc_user_nick_update(irc_user_t *iu, gboolean offline_only)
 {
 	bee_user_t *bu = iu->bu;
 	char *newnick;
 
-	if (bu->flags & BEE_USER_ONLINE) {
+	if (offline_only && bu->flags & BEE_USER_ONLINE) {
 		/* Ignore if the user is visible already. */
 		return TRUE;
@@ -432,5 +428,4 @@
 {
 	bee_user_t *bu = iu->bu;
-	bee_user_flags_t online;
 
 	if (bu == FALSE) {
@@ -438,13 +433,7 @@
 	}
 
-	/* In this case, pretend the user is offline. */
-	if ((online = bu->flags & BEE_USER_ONLINE)) {
-		bu->flags &= ~BEE_USER_ONLINE;
-	}
-
 	nick_del(bu);
-	bee_irc_user_nick_update(iu);
-
-	bu->flags |= online;
+	bee_irc_user_nick_update(iu, FALSE);
+
 }
 
@@ -1146,3 +1135,4 @@
 
 	bee_irc_log,
+	bee_irc_user_nick_change,
 };
Index: protocols/bee.h
===================================================================
--- protocols/bee.h	(revision 14f912d4c1e818d39234c874036e4fe60227d1dc)
+++ protocols/bee.h	(revision a42fda42abad6af64ac9a905856ee9a3095954cd)
@@ -131,4 +131,5 @@
 
 	void (*log)(bee_t *bee, const char *tag, const char *msg);
+	gboolean (*user_nick_change)(bee_t *bee, bee_user_t *bu, const char *hint);
 } bee_ui_funcs_t;
 
Index: protocols/nogaim.c
===================================================================
--- protocols/nogaim.c	(revision 14f912d4c1e818d39234c874036e4fe60227d1dc)
+++ protocols/nogaim.c	(revision a42fda42abad6af64ac9a905856ee9a3095954cd)
@@ -479,7 +479,6 @@
 }
 
-/* Mainly meant for ICQ (and now also for Jabber conferences) to allow IM
-   modules to suggest a nickname for a handle. */
-void imcb_buddy_nick_hint(struct im_connection *ic, const char *handle, const char *nick)
+/* Implements either imcb_buddy_nick_hint() or imcb_buddy_nick_change() depending on the value of 'change' */
+static void buddy_nick_hint_or_change(struct im_connection *ic, const char *handle, const char *nick, gboolean change)
 {
 	bee_t *bee = ic->bee;
@@ -493,9 +492,22 @@
 	bu->nick = g_strdup(nick);
 
-	if (bee->ui->user_nick_hint) {
+	if (change && bee->ui->user_nick_change) {
+		bee->ui->user_nick_change(bee, bu, nick);
+	} else if (!change && bee->ui->user_nick_hint) {
 		bee->ui->user_nick_hint(bee, bu, nick);
 	}
 }
 
+/* Soft variant, for newly created users. Does nothing if it's already online */
+void imcb_buddy_nick_hint(struct im_connection *ic, const char *handle, const char *nick)
+{
+	buddy_nick_hint_or_change(ic, handle, nick, FALSE);
+}
+
+/* Hard variant, always changes the nick */
+void imcb_buddy_nick_change(struct im_connection *ic, const char *handle, const char *nick)
+{
+	buddy_nick_hint_or_change(ic, handle, nick, TRUE);
+}
 
 struct imcb_ask_cb_data {
Index: protocols/nogaim.h
===================================================================
--- protocols/nogaim.h	(revision 14f912d4c1e818d39234c874036e4fe60227d1dc)
+++ protocols/nogaim.h	(revision a42fda42abad6af64ac9a905856ee9a3095954cd)
@@ -324,4 +324,5 @@
 G_MODULE_EXPORT void imcb_rename_buddy(struct im_connection *ic, const char *handle, const char *realname);
 G_MODULE_EXPORT void imcb_buddy_nick_hint(struct im_connection *ic, const char *handle, const char *nick);
+G_MODULE_EXPORT void imcb_buddy_nick_change(struct im_connection *ic, const char *handle, const char *nick);
 G_MODULE_EXPORT void imcb_buddy_action_response(bee_user_t *bu, const char *action, char * const args[], void *data);
 
