diff --git a/README b/README
index b8b2ec3..2b3ac27 100644
--- a/README
+++ b/README
@@ -15,6 +15,11 @@ Version 0.2
       LIBSSH2_CHANNEL_EXTENDED_DATA_MERGE      Calls to channel_read() will check both the standard data stream
                                                and the extended data stream(s) for the first available packet
 
+  Added libssh2_channel_flush_ex() and basic macros: ..._flush() ..._flush_stderr()
+    flush_ex accepts either the streamid (0 for standard data, 1 for stderr) or one of the two following constants:
+      LIBSSH2_CHANNEL_FLUSH_ALL                Flush all streams
+      LIBSSH2_CHANNEL_FLUSH_EXTENDED_DATA      Flush all streams EXCEPT the standard data stream
+
 Version 0.1
 -----------
 
diff --git a/include/libssh2.h b/include/libssh2.h
index d2e5840..392fb48 100644
--- a/include/libssh2.h
+++ b/include/libssh2.h
@@ -217,6 +217,11 @@ LIBSSH2_API void libssh2_channel_handle_extended_data(LIBSSH2_CHANNEL *channel,
 /* DEPRECATED */
 #define libssh2_channel_ignore_extended_data(channel, ignore)		libssh2_channel_handle_extended_data((channel), (ignore) ? LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE : LIBSSH2_CHANNEL_EXTENDED_DATA_NORMAL )
 
+#define LIBSSH2_CHANNEL_FLUSH_EXTENDED_DATA 	-1
+#define LIBSSH2_CHANNEL_FLUSH_ALL				-2
+LIBSSH2_API int libssh2_channel_flush_ex(LIBSSH2_CHANNEL *channel, int streamid);
+#define libssh2_channel_flush(channel)			libssh2_channel_flush_ex((channel), 0)
+#define libssh2_channel_flush_stderr(channel)	libssh2_channel_flush_ex((channel), SSH_EXTENDED_DATA_STDERR)
 
 LIBSSH2_API int libssh2_channel_send_eof(LIBSSH2_CHANNEL *channel);
 LIBSSH2_API int libssh2_channel_eof(LIBSSH2_CHANNEL *channel);
diff --git a/src/channel.c b/src/channel.c
index d9caee3..c3cbaac 100644
--- a/src/channel.c
+++ b/src/channel.c
@@ -434,27 +434,30 @@ LIBSSH2_API void libssh2_channel_set_blocking(LIBSSH2_CHANNEL *channel, int bloc
 }
 /* }}} */
 
-/* {{{ libssh2_channel_handle_extended_data
- * How should extended data look to the calling app?
- * Keep it in separate channels[_read() _read_stdder()]? (NORMAL)
- * Merge the extended data to the standard data? [everything via _read()]? (MERGE)
- * 
-Ignore it entirely [toss out packets as they come in]? (IGNORE)
+/* {{{ libssh2_channel_flush_ex
+ * Flush data from one (or all) stream
+ * Returns number of bytes flushed, or -1 on failure
  */
-LIBSSH2_API void libssh2_channel_handle_extended_data(LIBSSH2_CHANNEL *channel, int ignore_mode)
+LIBSSH2_API int libssh2_channel_flush_ex(LIBSSH2_CHANNEL *channel, int streamid)
 {
-	channel->remote.extended_data_ignore_mode = ignore_mode;
+	LIBSSH2_PACKET *packet = channel->session->packets.head;
+	unsigned long refund_bytes = 0, flush_bytes = 0;
 
-	if (ignore_mode == LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE) {
-		/* Flush queued extended data */
-		LIBSSH2_PACKET *packet = channel->session->packets.head;
-		unsigned long refund_bytes = 0;
+	while (packet) {
+		LIBSSH2_PACKET *next = packet->next;
+		unsigned char packet_type = packet->data[0];
 
-		while (packet) {
-			LIBSSH2_PACKET *next = packet->next;
+		if (((packet_type == SSH_MSG_CHANNEL_DATA) || (packet_type == SSH_MSG_CHANNEL_EXTENDED_DATA)) &&
+			(libssh2_ntohu32(packet->data + 1) == channel->local.id)) {
+			/* It's our channel at least */
+			if ((streamid == LIBSSH2_CHANNEL_FLUSH_ALL) ||
+				((packet_type == SSH_MSG_CHANNEL_EXTENDED_DATA) && ((streamid == LIBSSH2_CHANNEL_FLUSH_EXTENDED_DATA) || (streamid = libssh2_ntohu32(packet->data + 5)))) ||
+				((packet_type == SSH_MSG_CHANNEL_DATA) && (streamid == 0))) {
 
-			if ((packet->data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA) && (libssh2_ntohu32(packet->data + 1) == channel->local.id)) {
+				/* It's one of the streams we wanted to flush */
 				refund_bytes += packet->data_len - 13;
+				flush_bytes += packet->data_len - packet->data_head;
+
 				LIBSSH2_FREE(channel->session, packet->data);
 				if (packet->prev) {
 					packet->prev->next = packet->next;
@@ -468,23 +471,43 @@ LIBSSH2_API void libssh2_channel_handle_extended_data(LIBSSH2_CHANNEL *channel,
 				}
 				LIBSSH2_FREE(channel->session, packet);
 			}
-			packet = next;
 		}
-		if (refund_bytes && channel->remote.window_size_initial) {
-			unsigned char adjust[9]; /* packet_type(1) + channel(4) + adjustment(4) */
+		packet = next;
+	}
 
-			/* Adjust the window based on the block we just freed */
-			adjust[0] = SSH_MSG_CHANNEL_WINDOW_ADJUST;
-			libssh2_htonu32(adjust + 1, channel->remote.id);
-			libssh2_htonu32(adjust + 5, refund_bytes);
+	if (refund_bytes && channel->remote.window_size_initial) {
+		unsigned char adjust[9]; /* packet_type(1) + channel(4) + adjustment(4) */
 
-			if (libssh2_packet_write(channel->session, adjust, 9)) {
-				libssh2_error(channel->session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send transfer-window adjustment packet", 0);
-			} else {
-				channel->remote.window_size += refund_bytes;
-			}
+		/* Adjust the window based on the block we just freed */
+		adjust[0] = SSH_MSG_CHANNEL_WINDOW_ADJUST;
+		libssh2_htonu32(adjust + 1, channel->remote.id);
+		libssh2_htonu32(adjust + 5, refund_bytes);
+
+		if (libssh2_packet_write(channel->session, adjust, 9)) {
+			libssh2_error(channel->session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send transfer-window adjustment packet", 0);
+			return -1;
+		} else {
+			channel->remote.window_size += refund_bytes;
 		}
 	}
+
+	return flush_bytes;
+}
+/* }}} */
+
+/* {{{ libssh2_channel_handle_extended_data
+ * How should extended data look to the calling app?
+ * Keep it in separate channels[_read() _read_stdder()]? (NORMAL)
+ * Merge the extended data to the standard data? [everything via _read()]? (MERGE)
+ * Ignore it entirely [toss out packets as they come in]? (IGNORE)
+ */
+LIBSSH2_API void libssh2_channel_handle_extended_data(LIBSSH2_CHANNEL *channel, int ignore_mode)
+{
+	channel->remote.extended_data_ignore_mode = ignore_mode;
+
+	if (ignore_mode == LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE) {
+		libssh2_channel_flush_ex(channel, LIBSSH2_CHANNEL_FLUSH_EXTENDED_DATA);
+	}
 }
 /* }}} */