Index: irc.h
===================================================================
--- irc.h	(revision 241f9f6d9135048578ad603485740b73402edd8a)
+++ irc.h	(revision 1aa74f559af18e06195f34b721d65d69c29fcc0f)
@@ -282,4 +282,5 @@
 void irc_send_channel_user_mode_diff( irc_channel_t *ic, irc_user_t *iu,
                                       irc_channel_user_flags_t old, irc_channel_user_flags_t new );
+void irc_send_invite( irc_user_t *iu, irc_channel_t *ic );
 
 /* irc_user.c */
Index: irc_im.c
===================================================================
--- irc_im.c	(revision 241f9f6d9135048578ad603485740b73402edd8a)
+++ irc_im.c	(revision 1aa74f559af18e06195f34b721d65d69c29fcc0f)
@@ -613,4 +613,61 @@
 }
 
+static gboolean bee_irc_chat_invite( bee_t *bee, bee_user_t *bu, const char *name, const char *msg )
+{
+	char *channel, *s;
+	irc_t *irc = bee->ui_data;
+	irc_user_t *iu = bu->ui_data;
+	irc_channel_t *chan;
+	
+	if( strchr( CTYPES, name[0] ) )
+		channel = g_strdup( name );
+	else
+		channel = g_strdup_printf( "#%s", name );
+	
+	if( ( s = strchr( channel, '@' ) ) )
+		*s = '\0';
+	
+	if( strlen( channel ) > MAX_NICK_LENGTH )
+	{
+		/* If the channel name is very long (like those insane GTalk
+		   UUID names), try if we can use the inviter's nick. */
+		s = g_strdup_printf( "#%s", iu->nick );
+		if( irc_channel_by_name( irc, s ) == NULL )
+		{
+			g_free( channel );
+			channel = s;
+		}
+	}
+	
+	if( ( chan = irc_channel_new( irc, channel ) ) &&
+	    set_setstr( &chan->set, "type", "chat" ) &&
+	    set_setstr( &chan->set, "chat_type", "room" ) &&
+	    set_setstr( &chan->set, "account", bu->ic->acc->tag ) &&
+	    set_setstr( &chan->set, "room", (char*) name ) )
+	{
+		/* I'm assuming that if the user didn't "chat add" the room
+		   himself but got invited, it's temporary, so make this a
+		   temporary mapping that is removed as soon as we /PART. */
+		chan->flags |= IRC_CHANNEL_TEMP;
+	}
+	else
+	{
+		irc_channel_free( chan );
+		chan = NULL;
+	}
+	g_free( channel );
+	
+	irc_send_msg_f( iu, "PRIVMSG", irc->user->nick, "<< \002BitlBee\002 - Invitation to chatroom %s >>", name );
+	if( msg )
+		irc_send_msg( iu, "PRIVMSG", irc->user->nick, msg, NULL );
+	if( chan )
+	{
+		irc_send_msg_f( iu, "PRIVMSG", irc->user->nick, "To join the room, just /join %s", chan->name );
+		irc_send_invite( iu, chan );
+	}
+	
+	return TRUE;
+}
+
 /* IRC->IM */
 static gboolean bee_irc_channel_chat_privmsg_cb( gpointer data, gint fd, b_input_condition cond );
@@ -909,4 +966,5 @@
 	bee_irc_chat_topic,
 	bee_irc_chat_name_hint,
+	bee_irc_chat_invite,
 	
 	bee_irc_ft_in_start,
Index: irc_send.c
===================================================================
--- irc_send.c	(revision 241f9f6d9135048578ad603485740b73402edd8a)
+++ irc_send.c	(revision 1aa74f559af18e06195f34b721d65d69c29fcc0f)
@@ -398,2 +398,10 @@
 		irc_write( ic->irc, ":%s MODE %s %s", from, ic->name, changes );
 }
+
+void irc_send_invite( irc_user_t *iu, irc_channel_t *ic )
+{
+	irc_t *irc = iu->irc;
+	
+	irc_write( iu->irc, ":%s!%s@%s INVITE %s :%s",
+	           iu->nick, iu->user, iu->host, irc->user->nick, ic->name );
+}
Index: protocols/bee.h
===================================================================
--- protocols/bee.h	(revision 241f9f6d9135048578ad603485740b73402edd8a)
+++ protocols/bee.h	(revision 1aa74f559af18e06195f34b721d65d69c29fcc0f)
@@ -123,4 +123,5 @@
 	gboolean (*chat_topic)( bee_t *bee, struct groupchat *c, const char *new, bee_user_t *bu );
 	gboolean (*chat_name_hint)( bee_t *bee, struct groupchat *c, const char *name );
+	gboolean (*chat_invite)( bee_t *bee, bee_user_t *bu, const char *name, const char *msg );
 	
 	struct file_transfer* (*ft_in_start)( bee_t *bee, bee_user_t *bu, const char *file_name, size_t file_size );
@@ -175,4 +176,5 @@
 G_MODULE_EXPORT int bee_chat_msg( bee_t *bee, struct groupchat *c, const char *msg, int flags );
 G_MODULE_EXPORT struct groupchat *bee_chat_by_title( bee_t *bee, struct im_connection *ic, const char *title );
+G_MODULE_EXPORT void imcb_chat_invite( struct im_connection *ic, const char *name, const char *who, const char *msg );
 
 #endif /* __BEE_H__ */
Index: protocols/bee_chat.c
===================================================================
--- protocols/bee_chat.c	(revision 241f9f6d9135048578ad603485740b73402edd8a)
+++ protocols/bee_chat.c	(revision 1aa74f559af18e06195f34b721d65d69c29fcc0f)
@@ -233,2 +233,10 @@
 	return NULL;
 }
+
+void imcb_chat_invite( struct im_connection *ic, const char *name, const char *who, const char *msg )
+{
+	bee_user_t *bu = bee_user_by_handle( ic->bee, ic, who );
+	
+	if( bu && ic->bee->ui->chat_invite )
+		ic->bee->ui->chat_invite( ic->bee, bu, name, msg );
+}
Index: protocols/jabber/message.c
===================================================================
--- protocols/jabber/message.c	(revision 241f9f6d9135048578ad603485740b73402edd8a)
+++ protocols/jabber/message.c	(revision 1aa74f559af18e06195f34b721d65d69c29fcc0f)
@@ -31,5 +31,5 @@
 	struct xt_node *body = xt_find_node( node->children, "body" ), *c;
 	struct jabber_buddy *bud = NULL;
-	char *s;
+	char *s, *room = NULL, *reason = NULL;
 	
 	if( !from )
@@ -52,17 +52,17 @@
 		for( c = node->children; ( c = xt_find_node( c, "x" ) ); c = c->next )
 		{
-			char *ns = xt_find_attr( c, "xmlns" ), *room;
-			struct xt_node *inv, *reason;
+			char *ns = xt_find_attr( c, "xmlns" );
+			struct xt_node *inv;
 			
 			if( ns && strcmp( ns, XMLNS_MUC_USER ) == 0 &&
 			    ( inv = xt_find_node( c->children, "invite" ) ) )
 			{
+				/* This is an invitation. Set some vars which
+				   will be passed to imcb_chat_invite() below. */
 				room = from;
 				if( ( from = xt_find_attr( inv, "from" ) ) == NULL )
 					from = room;
-
-				g_string_append_printf( fullmsg, "<< \002BitlBee\002 - Invitation to chatroom %s >>\n", room );
-				if( ( reason = xt_find_node( inv->children, "reason" ) ) && reason->text_len > 0 )
-					g_string_append( fullmsg, reason->text );
+				if( ( inv = xt_find_node( inv->children, "reason" ) ) && inv->text_len > 0 )
+					reason = inv->text;
 			}
 		}
@@ -104,4 +104,6 @@
 			imcb_buddy_msg( ic, from, fullmsg->str,
 			                0, jabber_get_timestamp( node ) );
+		if( room )
+			imcb_chat_invite( ic, room, from, reason );
 		
 		g_string_free( fullmsg, TRUE );
