Index: doc/user-guide/commands.xml
===================================================================
--- doc/user-guide/commands.xml	(revision f4b0911d037c02f8b9190518b5efda4368dcc25b)
+++ doc/user-guide/commands.xml	(revision 3b878a1c3d0888b0669c30433efab914061fa61d)
@@ -861,4 +861,14 @@
 	</bitlbee-setting>
 
+	<bitlbee-setting name="show_offline" type="boolean" scope="global">
+		<default>true</default>
+
+		<description>
+			<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>
+		</description>
+	</bitlbee-setting>
+
 	<bitlbee-setting name="simulate_netsplit" type="boolean" scope="global">
 		<default>true</default>
Index: irc.c
===================================================================
--- irc.c	(revision f4b0911d037c02f8b9190518b5efda4368dcc25b)
+++ irc.c	(revision 3b878a1c3d0888b0669c30433efab914061fa61d)
@@ -201,4 +201,5 @@
 	s = set_add( &irc->set, "root_nick", irc->mynick, set_eval_root_nick, irc );
 	s = set_add( &irc->set, "save_on_quit", "true", set_eval_bool, irc );
+	s = set_add( &irc->set, "show_offline", "false", set_eval_bool, irc );
 	s = set_add( &irc->set, "simulate_netsplit", "true", set_eval_bool, irc );
 	s = set_add( &irc->set, "status", NULL,  set_eval_away_status, irc );
Index: lib/oauth.c
===================================================================
--- lib/oauth.c	(revision f4b0911d037c02f8b9190518b5efda4368dcc25b)
+++ lib/oauth.c	(revision 3b878a1c3d0888b0669c30433efab914061fa61d)
@@ -233,5 +233,5 @@
 }
 
-static void oauth_add_default_params( GSList **params, struct oauth_service *sp )
+static void oauth_add_default_params( GSList **params, const struct oauth_service *sp )
 {
 	char *s;
@@ -294,5 +294,5 @@
 static void oauth_request_token_done( struct http_request *req );
 
-struct oauth_info *oauth_request_token( struct oauth_service *sp, oauth_cb func, void *data )
+struct oauth_info *oauth_request_token( const struct oauth_service *sp, oauth_cb func, void *data )
 {
 	struct oauth_info *st = g_new0( struct oauth_info, 1 );
@@ -439,5 +439,5 @@
 }
 
-struct oauth_info *oauth_from_string( char *in, struct oauth_service *sp )
+struct oauth_info *oauth_from_string( char *in, const struct oauth_service *sp )
 {
 	struct oauth_info *oi = g_new0( struct oauth_info, 1 );
Index: lib/oauth.h
===================================================================
--- lib/oauth.h	(revision f4b0911d037c02f8b9190518b5efda4368dcc25b)
+++ lib/oauth.h	(revision 3b878a1c3d0888b0669c30433efab914061fa61d)
@@ -40,5 +40,5 @@
 {
 	oauth_stage_t stage;
-	struct oauth_service *sp;
+	const struct oauth_service *sp;
 	
 	oauth_cb func;
@@ -68,5 +68,5 @@
    authorization URL for the user. This is passed to the callback function
    in a struct oauth_info. */
-struct oauth_info *oauth_request_token( struct oauth_service *sp, oauth_cb func, void *data );
+struct oauth_info *oauth_request_token( const struct oauth_service *sp, oauth_cb func, void *data );
 
 /* http://oauth.net/core/1.0a/#auth_step3 (section 6.3)
@@ -88,3 +88,3 @@
 /* Convert to and back from strings, for easier saving. */
 char *oauth_to_string( struct oauth_info *oi );
-struct oauth_info *oauth_from_string( char *in, struct oauth_service *sp );
+struct oauth_info *oauth_from_string( char *in, const struct oauth_service *sp );
Index: protocols/nogaim.c
===================================================================
--- protocols/nogaim.c	(revision f4b0911d037c02f8b9190518b5efda4368dcc25b)
+++ protocols/nogaim.c	(revision 3b878a1c3d0888b0669c30433efab914061fa61d)
@@ -657,8 +657,19 @@
 	u->away = u->status_msg = NULL;
 	
-	if( ( flags & OPT_LOGGED_IN ) && !u->online )
-	{
+	if( set_getbool( &ic->irc->set, "show_offline" ) && !u->online )
+	{
+		/* always set users as online */
 		irc_spawn( ic->irc, u );
 		u->online = 1;
+		if( !( flags & OPT_LOGGED_IN ) )
+		{
+			/* set away message if user isn't really online */
+			u->away = g_strdup( "User is offline" );
+		}
+	}
+	else if( ( flags & OPT_LOGGED_IN ) && !u->online )
+	{
+		irc_spawn( ic->irc, u );
+		u->online = 1;
 	}
 	else if( !( flags & OPT_LOGGED_IN ) && u->online )
@@ -666,12 +677,28 @@
 		struct groupchat *c;
 		
-		irc_kill( ic->irc, u );
-		u->online = 0;
-		
-		/* Remove him/her from the groupchats to prevent PART messages after he/she QUIT already */
-		for( c = ic->groupchats; c; c = c->next )
-			remove_chat_buddy_silent( c, handle );
-	}
-	
+		if( set_getbool( &ic->irc->set, "show_offline" ) )
+		{
+			/* keep offline users in channel and set away message to "offline" */
+			u->away = g_strdup( "User is offline" );
+
+			/* Keep showing him/her in the control channel but not in groupchats. */
+			for( c = ic->groupchats; c; c = c->next )
+			{
+				if( remove_chat_buddy_silent( c, handle ) && c->joined )
+					irc_part( c->ic->irc, u, c->channel );
+			}
+		}
+		else
+		{
+			/* kill offline users */
+			irc_kill( ic->irc, u );
+			u->online = 0;
+
+			/* Remove him/her from the groupchats to prevent PART messages after he/she QUIT already */
+			for( c = ic->groupchats; c; c = c->next )
+				remove_chat_buddy_silent( c, handle );
+		}
+	}
+
 	if( flags & OPT_AWAY )
 	{
@@ -698,9 +725,6 @@
 	}
 	
-	/* LISPy... */
-	if( ( set_getbool( &ic->irc->set, "away_devoice" ) ) &&		/* Don't do a thing when user doesn't want it */
-	    ( u->online ) &&						/* Don't touch offline people */
-	    ( ( ( u->online != oo ) && !u->away ) ||			/* Voice joining people */
-	      ( ( u->online == oo ) && ( oa == !u->away ) ) ) )		/* (De)voice people changing state */
+	/* early if-clause for show_offline even if there is some redundant code here because this isn't LISP but C ;) */
+	if( set_getbool( &ic->irc->set, "show_offline" ) && set_getbool( &ic->irc->set, "away_devoice" ) )
 	{
 		char *from;
@@ -715,7 +739,41 @@
 			                                    ic->irc->myhost );
 		}
-		irc_write( ic->irc, ":%s MODE %s %cv %s", from, ic->irc->channel,
-		                                          u->away?'-':'+', u->nick );
-		g_free( from );
+
+		/* if we use show_offline, we op online users, voice away users, and devoice/deop offline users */
+		if( flags & OPT_LOGGED_IN )
+		{
+			/* user is "online" (either really online or away) */
+			irc_write( ic->irc, ":%s MODE %s %cv%co %s %s", from, ic->irc->channel,
+			                                          u->away?'+':'-', u->away?'-':'+', u->nick, u->nick );
+		}
+		else
+		{
+			/* user is offline */
+			irc_write( ic->irc, ":%s MODE %s -vo %s %s", from, ic->irc->channel, u->nick, u->nick );
+		}
+	}
+	else
+	{ 
+		/* LISPy... */
+		if( ( set_getbool( &ic->irc->set, "away_devoice" ) ) &&		/* Don't do a thing when user doesn't want it */
+		    ( u->online ) &&						/* Don't touch offline people */
+		    ( ( ( u->online != oo ) && !u->away ) ||			/* Voice joining people */
+		      ( ( u->online == oo ) && ( oa == !u->away ) ) ) )		/* (De)voice people changing state */
+		{
+			char *from;
+
+			if( set_getbool( &ic->irc->set, "simulate_netsplit" ) )
+			{
+				from = g_strdup( ic->irc->myhost );
+			}
+			else
+			{
+				from = g_strdup_printf( "%s!%s@%s", ic->irc->mynick, ic->irc->mynick,
+				                                    ic->irc->myhost );
+			}
+			irc_write( ic->irc, ":%s MODE %s %cv %s", from, ic->irc->channel,
+			                                          u->away?'-':'+', u->nick );
+			g_free( from );
+		}
 	}
 }
@@ -1194,5 +1252,5 @@
 		return g_strdup_printf( "\x02[\x02\x02\x02%04d-%02d-%02d "
 		                        "%02d:%02d:%02d\x02]\x02 ",
-		                        msg.tm_year + 1900, msg.tm_mon, msg.tm_mday,
+		                        msg.tm_year + 1900, msg.tm_mon + 1, msg.tm_mday,
 		                        msg.tm_hour, msg.tm_min, msg.tm_sec );
 }
Index: protocols/twitter/twitter.c
===================================================================
--- protocols/twitter/twitter.c	(revision f4b0911d037c02f8b9190518b5efda4368dcc25b)
+++ protocols/twitter/twitter.c	(revision 3b878a1c3d0888b0669c30433efab914061fa61d)
@@ -66,5 +66,5 @@
 
 
-static struct oauth_service twitter_oauth =
+static const struct oauth_service twitter_oauth =
 {
 	"http://api.twitter.com/oauth/request_token",
@@ -115,5 +115,5 @@
 	else if( info->stage == OAUTH_ACCESS_TOKEN )
 	{
-		if( info->token == NULL )
+		if( info->token == NULL || info->token_secret == NULL )
 		{
 			imcb_error( ic, "OAuth error: %s", info->http->status_string );
