Index: doc/user-guide/commands.xml
===================================================================
--- doc/user-guide/commands.xml	(revision 94d5da9cc78a89b6292d53c7784a3076500d67e2)
+++ doc/user-guide/commands.xml	(revision 6d8cc053c4b247ad721a0760b13cd383d758c2c5)
@@ -518,4 +518,8 @@
 				With this option enabled, the root user devoices people when they go away (just away, not offline) and gives the voice back when they come back. You might dislike the voice-floods you'll get if your contact list is huge, so this option can be disabled.
 			</para>
+			
+			<para>
+				Replaced with the <emphasis>show_users</emphasis> setting. See <emphasis>help show_users</emphasis>.
+			</para>
 		</description>
 	</bitlbee-setting>
@@ -1040,4 +1044,30 @@
 			<para>
 				If enabled causes BitlBee to also show offline users in Channel. Online-users will get op, away-users voice and offline users none of both. This option takes effect as soon as you reconnect.
+			</para>
+			
+			<para>
+				Replaced with the <emphasis>show_users</emphasis> setting. See <emphasis>help show_users</emphasis>.
+			</para>
+		</description>
+	</bitlbee-setting>
+
+	<bitlbee-setting name="show_users" type="string" scope="channel">
+		<default>online+,away</default>
+
+		<description>
+			<para>
+				Comma-separated list of statuses of users you want in the channel,
+				and any modes they should have. The following statuses are currently
+				recognised: <emphasis>online</emphasis> (i.e. available, not
+				away), <emphasis>away</emphasis>, and <emphasis>offline</emphasis>.
+			</para>
+			
+			<para>
+				If a status is followed by a valid channel mode character
+				(@, % or +), it will be given to users with that status.
+				For example, <emphasis>online@,away+,offline</emphasis> will
+				show all users in the channel. Online people will
+				have +o, people who are online but away will have +v,
+				and others will have no special modes.
 			</para>
 		</description>
Index: irc.c
===================================================================
--- irc.c	(revision 94d5da9cc78a89b6292d53c7784a3076500d67e2)
+++ irc.c	(revision 6d8cc053c4b247ad721a0760b13cd383d758c2c5)
@@ -33,4 +33,5 @@
 static char *set_eval_charset( set_t *set, char *value );
 static char *set_eval_password( set_t *set, char *value );
+static char *set_eval_bw_compat( set_t *set, char *value );
 
 irc_t *irc_new( int fd )
@@ -101,5 +102,5 @@
 	
 	s = set_add( &b->set, "allow_takeover", "true", set_eval_bool, irc );
-	s = set_add( &b->set, "away_devoice", "true", set_eval_away_devoice, irc );
+	s = set_add( &b->set, "away_devoice", "true", set_eval_bw_compat, irc );
 	s = set_add( &b->set, "away_reply_timeout", "3600", set_eval_int, irc );
 	s = set_add( &b->set, "charset", "utf-8", set_eval_charset, irc );
@@ -121,4 +122,5 @@
 	s = set_add( &b->set, "query_order", "lifo", NULL, irc );
 	s = set_add( &b->set, "root_nick", ROOT_NICK, set_eval_root_nick, irc );
+	s = set_add( &b->set, "show_offline", "false", set_eval_bw_compat, irc );
 	s = set_add( &b->set, "simulate_netsplit", "true", set_eval_bool, irc );
 	s = set_add( &b->set, "timezone", "local", set_eval_timezone, irc );
@@ -901,18 +903,30 @@
 }
 
-char *set_eval_away_devoice( set_t *set, char *value )
+/* Mostly meant for upgrades. If one of these is set to the non-default,
+   set show_users of all channels to something with the same effect. */
+static char *set_eval_bw_compat( set_t *set, char *value )
 {
 	irc_t *irc = set->data;
-	
-	if( !is_bool( value ) )
+	char *val;
+	GSList *l;
+	
+	irc_usermsg( irc, "Setting `%s' is obsolete, use the `show_users' "
+	             "channel setting instead.", set->key );
+	
+	if( strcmp( set->key, "away_devoice" ) == 0 && !bool2int( value ) )
+		val = "online,away";
+	else if( strcmp( set->key, "show_offline" ) == 0 && bool2int( value ) )
+		val = "online@,away+,offline";
+	else
 		return SET_INVALID;
 	
-	/* The usual problem: The setting isn't actually changed at this
-	   point and we need it to be, so do it by hand. */
-	g_free( set->value );
-	set->value = g_strdup( value );
-	
-	bee_irc_channel_update( irc, NULL, NULL );
-	
-	return value;
-}
+	for( l = irc->channels; l; l = l->next )
+	{
+		irc_channel_t *ic = l->data;
+		/* No need to check channel type, if the setting doesn't exist it
+		   will just be ignored. */
+		set_setstr( &ic->set, "show_users", val );
+	}
+	
+	return SET_INVALID;
+}
Index: protocols/nogaim.h
===================================================================
--- protocols/nogaim.h	(revision 94d5da9cc78a89b6292d53c7784a3076500d67e2)
+++ protocols/nogaim.h	(revision 6d8cc053c4b247ad721a0760b13cd383d758c2c5)
@@ -324,5 +324,4 @@
 /* Misc. stuff */
 char *set_eval_timezone( set_t *set, char *value );
-char *set_eval_away_devoice( set_t *set, char *value );
 gboolean auto_reconnect( gpointer data, gint fd, b_input_condition cond );
 void cancel_auto_reconnect( struct account *a );
