Index: bitlbee.c
===================================================================
--- bitlbee.c	(revision c5bff810e6919dc3daf7f82f761197a27f04538b)
+++ bitlbee.c	(revision b556e46f9bfeeb630b45a3c0f0951110ac3de0f2)
@@ -372,5 +372,6 @@
 	/* Try to save data for all active connections (if desired). */
 	while( irc_connection_list != NULL )
-		irc_free( irc_connection_list->data );
+		irc_abort( irc_connection_list->data, FALSE,
+		           "BitlBee server shutting down" );
 	
 	/* We'll only reach this point when not running in inetd mode: */
Index: doc/user-guide/commands.xml
===================================================================
--- doc/user-guide/commands.xml	(revision c5bff810e6919dc3daf7f82f761197a27f04538b)
+++ doc/user-guide/commands.xml	(revision b556e46f9bfeeb630b45a3c0f0951110ac3de0f2)
@@ -1093,4 +1093,18 @@
 	</bitlbee-setting>
 
+	<bitlbee-setting name="translate_to_nicks" type="boolean" scope="channel">
+		<default>true</default>
+
+		<description>
+			<para>
+				IRC's nickname namespace is quite limited compared to most IM protocols. Not any non-ASCII characters are allowed, in fact nicknames have to be mostly alpha-numeric. Also, BitlBee has to add underscores sometimes to avoid nickname collisions.
+			</para>
+
+			<para>
+				While normally the BitlBee user is the only one seeing these names, they may be exposed to other chatroom participants for example when addressing someone in the channel (with or without tab completion). By default BitlBee will translate these stripped nicknames back to the original nick. If you don't want this, disable this setting.
+			</para>
+		</description>
+	</bitlbee-setting>
+
 	<bitlbee-setting name="type" type="string" scope="channel">
 		<default>control</default>
Index: irc_commands.c
===================================================================
--- irc_commands.c	(revision c5bff810e6919dc3daf7f82f761197a27f04538b)
+++ irc_commands.c	(revision b556e46f9bfeeb630b45a3c0f0951110ac3de0f2)
@@ -72,14 +72,16 @@
 static void irc_cmd_nick( irc_t *irc, char **cmd )
 {
-	if( irc_user_by_name( irc, cmd[1] ) )
-	{
-		irc_send_num( irc, 433, ":This nick is already in use" );
+	irc_user_t *iu;
+	
+	if( ( iu = irc_user_by_name( irc, cmd[1] ) ) && iu != irc->user )
+	{
+		irc_send_num( irc, 433, "%s :This nick is already in use", cmd[1] );
 	}
 	else if( !nick_ok( cmd[1] ) )
 	{
 		/* [SH] Invalid characters. */
-		irc_send_num( irc, 432, ":This nick contains invalid characters" );
-	}
-	else if( irc->user->nick )
+		irc_send_num( irc, 432, "%s :This nick contains invalid characters", cmd[1] );
+	}
+	else if( irc->status & USTATUS_LOGGED_IN )
 	{
 		if( irc->status & USTATUS_IDENTIFIED )
@@ -98,4 +100,5 @@
 	else
 	{
+		g_free( irc->user->nick );
 		irc->user->nick = g_strdup( cmd[1] );
 		
Index: irc_im.c
===================================================================
--- irc_im.c	(revision c5bff810e6919dc3daf7f82f761197a27f04538b)
+++ irc_im.c	(revision b556e46f9bfeeb630b45a3c0f0951110ac3de0f2)
@@ -603,8 +603,29 @@
 {
 	struct groupchat *c = ic->data;
+	char *trans = NULL, *s;
 	
 	if( c == NULL )
 		return FALSE;
-	else if( set_getbool( &ic->irc->b->set, "paste_buffer" ) )
+	
+	if( set_getbool( &ic->set, "translate_to_nicks" ) )
+	{
+		char nick[MAX_NICK_LENGTH+1];
+		irc_user_t *iu;
+		
+		strncpy( nick, msg, MAX_NICK_LENGTH );
+		nick[MAX_NICK_LENGTH] = '\0';
+		if( ( s = strchr( nick, ':' ) ) || ( s = strchr( nick, ',' ) ) )
+		{
+			*s = '\0';
+			if( ( iu = irc_user_by_name( ic->irc, nick ) ) &&
+			    iu->bu->nick && irc_channel_has_user( ic, iu ) )
+			{
+				trans = g_strconcat( iu->bu->nick, msg + ( s - nick ), NULL );
+				msg = trans;
+			}
+		}
+	}
+	
+	if( set_getbool( &ic->irc->b->set, "paste_buffer" ) )
 	{
 		int delay;
@@ -623,4 +644,5 @@
 		ic->pastebuf_timer = b_timeout_add( delay, bee_irc_channel_chat_privmsg_cb, ic );
 		
+		g_free( trans );
 		return TRUE;
 	}
@@ -628,4 +650,5 @@
 		bee_chat_msg( ic->irc->b, c, msg, 0 );
 	
+	g_free( trans );
 	return TRUE;
 }
@@ -747,4 +770,5 @@
 	set_add( &ic->set, "nick", NULL, NULL, ic );
 	set_add( &ic->set, "room", NULL, NULL, ic );
+	set_add( &ic->set, "translate_to_nicks", "true", set_eval_bool, ic );
 	
 	/* chat_type == groupchat */
@@ -790,4 +814,5 @@
 	set_del( &ic->set, "nick" );
 	set_del( &ic->set, "room" );
+	set_del( &ic->set, "translate_to_nicks" );
 	
 	ic->flags &= ~IRC_CHANNEL_TEMP;
Index: irc_user.c
===================================================================
--- irc_user.c	(revision c5bff810e6919dc3daf7f82f761197a27f04538b)
+++ irc_user.c	(revision b556e46f9bfeeb630b45a3c0f0951110ac3de0f2)
@@ -121,9 +121,11 @@
 {
 	irc_t *irc = iu->irc;
+	irc_user_t *new_iu;
 	char key[strlen(new)+1];
 	GSList *cl;
 	
 	strcpy( key, new );
-	if( iu == NULL || !nick_lc( key ) || irc_user_by_name( irc, new ) )
+	if( iu == NULL || !nick_lc( key ) ||
+	    ( ( new_iu = irc_user_by_name( irc, new ) ) && new_iu != iu ) )
 		return 0;
 	
Index: protocols/bee.h
===================================================================
--- protocols/bee.h	(revision c5bff810e6919dc3daf7f82f761197a27f04538b)
+++ protocols/bee.h	(revision b556e46f9bfeeb630b45a3c0f0951110ac3de0f2)
@@ -62,4 +62,5 @@
 	char *handle;
 	char *fullname;
+	char *nick;
 	struct bee_group *group;
 
Index: protocols/bee_user.c
===================================================================
--- protocols/bee_user.c	(revision c5bff810e6919dc3daf7f82f761197a27f04538b)
+++ protocols/bee_user.c	(revision b556e46f9bfeeb630b45a3c0f0951110ac3de0f2)
@@ -60,4 +60,5 @@
 	g_free( bu->handle );
 	g_free( bu->fullname );
+	g_free( bu->nick );
 	g_free( bu->status );
 	g_free( bu->status_msg );
Index: protocols/nogaim.c
===================================================================
--- protocols/nogaim.c	(revision c5bff810e6919dc3daf7f82f761197a27f04538b)
+++ protocols/nogaim.c	(revision b556e46f9bfeeb630b45a3c0f0951110ac3de0f2)
@@ -427,4 +427,7 @@
 	
 	if( !bu || !nick ) return;
+	
+	g_free( bu->nick );
+	bu->nick = g_strdup( nick );
 	
 	if( bee->ui->user_nick_hint )
Index: root_commands.c
===================================================================
--- root_commands.c	(revision c5bff810e6919dc3daf7f82f761197a27f04538b)
+++ root_commands.c	(revision b556e46f9bfeeb630b45a3c0f0951110ac3de0f2)
@@ -680,5 +680,5 @@
 static void cmd_rename( irc_t *irc, char **cmd )
 {
-	irc_user_t *iu;
+	irc_user_t *iu, *old;
 	
 	iu = irc_user_by_name( irc, cmd[1] );
@@ -696,5 +696,5 @@
 		irc_usermsg( irc, "Nick `%s' is invalid", cmd[2] );
 	}
-	else if( irc_user_by_name( irc, cmd[2] ) )
+	else if( ( old = irc_user_by_name( irc, cmd[2] ) ) && old != iu )
 	{
 		irc_usermsg( irc, "Nick `%s' already exists", cmd[2] );
