Thanks for the detailed analysis and also for the pull-request.. We love contributions :)

I merged your patch in and it will be part of 3.5.8.Final

pipelining + suspended ChunkedInput triggers StackOverflowError in ChunkedWriteHandler.flush()
We encountered an issue with ChunkedWriteHandler (netty version 3.5.7).

We get StackOverflowError in following scenario:
- ChunkWriteHandler.queue is not empty
- ChunkedWriteHandler.currentEvent is not null and it stores ChunkedInput as message
- chunkedInput stored in currentEvent is in suspended mode (nextChunk returns null but isEndOfInput returns false).

In such case break from while loop in line 248 is executed.
But then immediately after that flush() is called again recursively in line 301, because condition in line 300 evaluates to true.

If chunkedInput is in suspended mode long enough we get StackOverFlowException.

As a fix I moved suspend variable above while loop and modified condition in line 300 to:

```
if (acquired && (!channel.isConnected() || channel.isWritable() && (!queue.isEmpty() && !suspend))) { 
```

I am not exactly sure if it does not break something but it seems to fix an issue.

src/main/java/org/jboss/netty/handler/stream/ChunkedWriteHandler.java
src/main/java/org/jboss/netty/handler/stream/ChunkedWriteHandler.java
diff --git a/src/main/java/org/jboss/netty/handler/stream/ChunkedWriteHandler.java b/src/main/java/org/jboss/netty/handler/stream/ChunkedWriteHandler.java
index 0cb6d4ef55c..e06c45b4608 100644
--- a/src/main/java/org/jboss/netty/handler/stream/ChunkedWriteHandler.java
+++ b/src/main/java/org/jboss/netty/handler/stream/ChunkedWriteHandler.java
@@ -186,6 +186,7 @@ private void discard(ChannelHandlerContext ctx, boolean fireNow) {
     private void flush(ChannelHandlerContext ctx, boolean fireNow) throws Exception {
         boolean acquired = false;
         final Channel channel = ctx.getChannel();
+        boolean suspend = false;
 
         // use CAS to see if the have flush already running, if so we don't need to take futher actions
         if (acquired = flush.compareAndSet(false, true)) {
@@ -216,7 +217,6 @@ private void flush(ChannelHandlerContext ctx, boolean fireNow) throws Exception
                             final ChunkedInput chunks = (ChunkedInput) m;
                             Object chunk;
                             boolean endOfInput;
-                            boolean suspend;
                             try {
                                 chunk = chunks.nextChunk();
                                 endOfInput = chunks.isEndOfInput();
@@ -297,7 +297,7 @@ public void operationComplete(ChannelFuture future) throws Exception {
 
         }
 
-        if (acquired && (!channel.isConnected() || channel.isWritable() && !queue.isEmpty())) {
+        if (acquired && (!channel.isConnected() || channel.isWritable() && !queue.isEmpty() && !suspend)) {
             flush(ctx, fireNow);
         }
     }
