Index: doc/user-guide/commands.xml
===================================================================
--- doc/user-guide/commands.xml	(revision 203a2d2e8857e4c83f8f5e1a89de03ea08538cb2)
+++ doc/user-guide/commands.xml	(revision b8906261293b34d8c792bd1f48df10144a8a8f10)
@@ -495,4 +495,22 @@
 	</bitlbee-setting>
 
+	<bitlbee-setting name="auto_reply_timeout" type="integer" scope="account">
+		<default>10800</default>
+
+		<description>
+			<para>
+				For Twitter accounts: If you respond to Tweets IRC-style (like "nickname: reply"), this will automatically be converted to the usual Twitter format ("@screenname reply").
+			</para>
+
+			<para>
+				By default, BitlBee will then also add a reference to that person's most recent Tweet, unless that message is older than the value of this setting in seconds.
+			</para>
+
+			<para>
+				If you want to disable this feature, just set this to 0. Alternatively, if you want to write a message once that is <emphasis>not</emphasis> a reply, use the Twitter reply syntax (@screenname).
+			</para>
+		</description>
+	</bitlbee-setting>
+
 	<bitlbee-setting name="away" type="string" scope="both">
 		<description>
@@ -598,4 +616,26 @@
 			<para>
 				For setting up named chatrooms, it's currently easier to just use the <emphasis>chat add</emphasis> command.
+			</para>
+		</description>
+	</bitlbee-setting>
+
+	<bitlbee-setting name="commands" type="boolean" scope="account">
+		<default>true</default>
+
+		<description>
+			<para>
+				With this setting enabled, you can use some commands in your Twitter channel/query. The commands are simple and not documented in too much detail:
+			</para>
+
+			<variablelist>
+				<varlistentry><term>undo [&lt;id&gt;]</term><listitem><para>Delete your last Tweet (or one with the given ID)</para></listitem></varlistentry>
+				<varlistentry><term>rt &lt;screenname|id&gt;</term><listitem><para>Retweet someone's last Tweet (or one with the given ID)</para></listitem></varlistentry>
+				<varlistentry><term>follow &lt;screenname&gt;</term><listitem><para>Start following a person</para></listitem></varlistentry>
+				<varlistentry><term>unfollow &lt;screenname&gt;</term><listitem><para>Stop following a person</para></listitem></varlistentry>
+				<varlistentry><term>post &lt;message&gt;</term><listitem><para>Post a tweet</para></listitem></varlistentry>
+			</variablelist>
+
+			<para>
+				Anything that doesn't look like a command will be treated as a tweet. Watch out for typos! :-)
 			</para>
 		</description>
Index: protocols/twitter/twitter.c
===================================================================
--- protocols/twitter/twitter.c	(revision 203a2d2e8857e4c83f8f5e1a89de03ea08538cb2)
+++ protocols/twitter/twitter.c	(revision b8906261293b34d8c792bd1f48df10144a8a8f10)
@@ -186,4 +186,6 @@
 	}
 	
+	s = set_add( &acc->set, "auto_reply_timeout", "10800", set_eval_int, acc );
+	
 	s = set_add( &acc->set, "base_url", def_url, NULL, acc );
 	s->flags |= ACC_SET_OFFLINE_ONLY;
@@ -427,11 +429,5 @@
 		
 		if( cmd[1] )
-		{
-			char *end = NULL;
-			
-			id = g_ascii_strtoull( cmd[1], &end, 10 );
-			if( end == NULL )
-				id = 0;
-		}
+			id = g_ascii_strtoull( cmd[1], NULL, 10 );
 		else
 			id = td->last_status_id;
@@ -444,4 +440,35 @@
 		return;
 	}
+	else if( g_strcasecmp( cmd[0], "follow" ) == 0 && cmd[1] )
+	{
+		twitter_add_buddy( ic, cmd[1], NULL );
+		g_free( cmds );
+		return;
+	}
+	else if( g_strcasecmp( cmd[0], "unfollow" ) == 0 && cmd[1] )
+	{
+		twitter_remove_buddy( ic, cmd[1], NULL );
+		g_free( cmds );
+		return;
+	}
+	else if( g_strcasecmp( cmd[0], "rt" ) == 0 && cmd[1] )
+	{
+		struct twitter_user_data *tud;
+		bee_user_t *bu;
+		guint64 id;
+		
+		if( ( bu = bee_user_by_handle( ic->bee, ic, cmd[1] ) ) &&
+		    ( tud = bu->data ) && tud->last_id )
+			id = tud->last_id;
+		else
+			id = g_ascii_strtoull( cmd[1], NULL, 10 );
+		
+		td->last_status_id = 0;
+		if( id )
+			twitter_status_retweet( ic, id );
+		
+		g_free( cmds );
+		return;
+	}
 	else if( g_strcasecmp( cmd[0], "post" ) == 0 )
 	{
@@ -450,4 +477,5 @@
 	
 	{
+		guint64 in_reply_to = 0;
 		char *s, *new = NULL;
 		bee_user_t *bu;
@@ -466,11 +494,20 @@
 			if( ( bu = bee_user_by_handle( ic->bee, ic, cmd[0] ) ) )
 			{
+				struct twitter_user_data *tud = bu->data;
+				
 				new = g_strdup_printf( "@%s %s", bu->handle,
 				                       message + ( s - cmd[0] ) + 2 );
 				message = new;
+				
+				if( time( NULL ) < tud->last_time +
+				    set_getint( &ic->acc->set, "auto_reply_timeout" ) )
+					in_reply_to = tud->last_id;
 			}
 		}
 		
-		twitter_post_status( ic, message );
+		/* If the user runs undo between this request and its response
+		   this would delete the second-last Tweet. Prevent that. */
+		td->last_status_id = 0;
+		twitter_post_status( ic, message, in_reply_to );
 		g_free( new );
 	}
Index: protocols/twitter/twitter_lib.c
===================================================================
--- protocols/twitter/twitter_lib.c	(revision 203a2d2e8857e4c83f8f5e1a89de03ea08538cb2)
+++ protocols/twitter/twitter_lib.c	(revision b8906261293b34d8c792bd1f48df10144a8a8f10)
@@ -784,11 +784,14 @@
  * Function to POST a new status to twitter.
  */ 
-void twitter_post_status(struct im_connection *ic, char* msg)
-{
-	char* args[2];
-	args[0] = "status";
-	args[1] = msg;
-	twitter_http(ic, TWITTER_STATUS_UPDATE_URL, twitter_http_post, ic, 1, args, 2);
-//	g_free(args[1]);
+void twitter_post_status(struct im_connection *ic, char *msg, guint64 in_reply_to)
+{
+	char* args[4] = {
+		"status", msg,
+		"in_reply_to_status_id",
+		g_strdup_printf("%llu", (unsigned long long) in_reply_to)
+	};
+	twitter_http(ic, TWITTER_STATUS_UPDATE_URL, twitter_http_post, ic, 1,
+	             args, in_reply_to ? 4 : 2);
+	g_free(args[3]);
 }
 
@@ -825,2 +828,10 @@
 	g_free(url);
 }
+
+void twitter_status_retweet(struct im_connection *ic, guint64 id)
+{
+	char *url;
+	url = g_strdup_printf("%s%llu%s", TWITTER_STATUS_RETWEET_URL, (unsigned long long) id, ".xml");
+	twitter_http(ic, url, twitter_http_post, ic, 1, NULL, 0);
+	g_free(url);
+}
Index: protocols/twitter/twitter_lib.h
===================================================================
--- protocols/twitter/twitter_lib.h	(revision 203a2d2e8857e4c83f8f5e1a89de03ea08538cb2)
+++ protocols/twitter/twitter_lib.h	(revision b8906261293b34d8c792bd1f48df10144a8a8f10)
@@ -36,4 +36,5 @@
 #define TWITTER_STATUS_SHOW_URL "/statuses/show/"
 #define TWITTER_STATUS_DESTROY_URL "/statuses/destroy/"
+#define TWITTER_STATUS_RETWEET_URL "/statuses/retweet/"
 
 /* Timeline URLs */
@@ -81,8 +82,9 @@
 void twitter_get_statuses_friends(struct im_connection *ic, gint64 next_cursor);
 
-void twitter_post_status(struct im_connection *ic, char *msg);
+void twitter_post_status(struct im_connection *ic, char *msg, guint64 in_reply_to);
 void twitter_direct_messages_new(struct im_connection *ic, char *who, char *message);
 void twitter_friendships_create_destroy(struct im_connection *ic, char *who, int create);
 void twitter_status_destroy(struct im_connection *ic, guint64 id);
+void twitter_status_retweet(struct im_connection *ic, guint64 id);
 
 #endif //_TWITTER_LIB_H
