diff src/org/eclipse/jetty/server/AsyncContinuation.java @ 865:6b210bb66c63

remove ThreadPool
author Franklin Schmidt <fschmidt@gmail.com>
date Sun, 02 Oct 2016 20:38:06 -0600
parents 8e9db0bbf4f9
children b9aa175d9a29
line wrap: on
line diff
--- a/src/org/eclipse/jetty/server/AsyncContinuation.java	Sun Oct 02 16:17:38 2016 -0600
+++ b/src/org/eclipse/jetty/server/AsyncContinuation.java	Sun Oct 02 20:38:06 2016 -0600
@@ -50,1111 +50,1111 @@
  */
 public class AsyncContinuation implements AsyncContext, Continuation
 {
-    private static final Logger LOG = LoggerFactory.getLogger(AsyncContinuation.class);
+	private static final Logger LOG = LoggerFactory.getLogger(AsyncContinuation.class);
 
-    private final static long DEFAULT_TIMEOUT=30000L;
-    
-    private final static ContinuationThrowable __exception = new ContinuationThrowable();
-    
-    // STATES:
-    //               handling()    suspend()     unhandle()    resume()       complete()  doComplete()
-    //                             startAsync()                dispatch()   
-    // IDLE          DISPATCHED      
-    // DISPATCHED                  ASYNCSTARTED  UNCOMPLETED
-    // ASYNCSTARTED                              ASYNCWAIT     REDISPATCHING  COMPLETING
-    // REDISPATCHING                             REDISPATCHED  
-    // ASYNCWAIT                                               REDISPATCH     COMPLETING
-    // REDISPATCH    REDISPATCHED
-    // REDISPATCHED                ASYNCSTARTED  UNCOMPLETED
-    // COMPLETING    UNCOMPLETED                 UNCOMPLETED
-    // UNCOMPLETED                                                                        COMPLETED
-    // COMPLETED
-    private static final int __IDLE=0;         // Idle request
-    private static final int __DISPATCHED=1;   // Request dispatched to filter/servlet
-    private static final int __ASYNCSTARTED=2; // Suspend called, but not yet returned to container
-    private static final int __REDISPATCHING=3;// resumed while dispatched
-    private static final int __ASYNCWAIT=4;    // Suspended and parked
-    private static final int __REDISPATCH=5;   // Has been scheduled
-    private static final int __REDISPATCHED=6; // Request redispatched to filter/servlet
-    private static final int __COMPLETING=7;   // complete while dispatched
-    private static final int __UNCOMPLETED=8;  // Request is completable
-    private static final int __COMPLETED=9;    // Request is complete
-    
-    /* ------------------------------------------------------------ */
-    protected AbstractHttpConnection _connection;
-    private List<AsyncListener> _lastAsyncListeners;
-    private List<AsyncListener> _asyncListeners;
-    private List<ContinuationListener> _continuationListeners;
+	private final static long DEFAULT_TIMEOUT=30000L;
+	
+	private final static ContinuationThrowable __exception = new ContinuationThrowable();
+	
+	// STATES:
+	//               handling()    suspend()     unhandle()    resume()       complete()  doComplete()
+	//                             startAsync()                dispatch()   
+	// IDLE          DISPATCHED      
+	// DISPATCHED                  ASYNCSTARTED  UNCOMPLETED
+	// ASYNCSTARTED                              ASYNCWAIT     REDISPATCHING  COMPLETING
+	// REDISPATCHING                             REDISPATCHED  
+	// ASYNCWAIT                                               REDISPATCH     COMPLETING
+	// REDISPATCH    REDISPATCHED
+	// REDISPATCHED                ASYNCSTARTED  UNCOMPLETED
+	// COMPLETING    UNCOMPLETED                 UNCOMPLETED
+	// UNCOMPLETED                                                                        COMPLETED
+	// COMPLETED
+	private static final int __IDLE=0;         // Idle request
+	private static final int __DISPATCHED=1;   // Request dispatched to filter/servlet
+	private static final int __ASYNCSTARTED=2; // Suspend called, but not yet returned to container
+	private static final int __REDISPATCHING=3;// resumed while dispatched
+	private static final int __ASYNCWAIT=4;    // Suspended and parked
+	private static final int __REDISPATCH=5;   // Has been scheduled
+	private static final int __REDISPATCHED=6; // Request redispatched to filter/servlet
+	private static final int __COMPLETING=7;   // complete while dispatched
+	private static final int __UNCOMPLETED=8;  // Request is completable
+	private static final int __COMPLETED=9;    // Request is complete
+	
+	/* ------------------------------------------------------------ */
+	protected AbstractHttpConnection _connection;
+	private List<AsyncListener> _lastAsyncListeners;
+	private List<AsyncListener> _asyncListeners;
+	private List<ContinuationListener> _continuationListeners;
 
-    /* ------------------------------------------------------------ */
-    private int _state;
-    private boolean _initial;
-    private boolean _resumed;
-    private boolean _expired;
-    private volatile boolean _responseWrapped;
-    private long _timeoutMs=DEFAULT_TIMEOUT;
-    private AsyncEventState _event;
-    private volatile long _expireAt;    
-    private volatile boolean _continuation;
-    
-    /* ------------------------------------------------------------ */
-    protected AsyncContinuation()
-    {
-        _state=__IDLE;
-        _initial=true;
-    }
+	/* ------------------------------------------------------------ */
+	private int _state;
+	private boolean _initial;
+	private boolean _resumed;
+	private boolean _expired;
+	private volatile boolean _responseWrapped;
+	private long _timeoutMs=DEFAULT_TIMEOUT;
+	private AsyncEventState _event;
+	private volatile long _expireAt;    
+	private volatile boolean _continuation;
+	
+	/* ------------------------------------------------------------ */
+	protected AsyncContinuation()
+	{
+		_state=__IDLE;
+		_initial=true;
+	}
 
-    /* ------------------------------------------------------------ */
-    protected void setConnection(final AbstractHttpConnection connection)
-    {
-        synchronized(this)
-        {
-            _connection=connection;
-        }
-    }
+	/* ------------------------------------------------------------ */
+	protected void setConnection(final AbstractHttpConnection connection)
+	{
+		synchronized(this)
+		{
+			_connection=connection;
+		}
+	}
 
-    /* ------------------------------------------------------------ */
-    public void addListener(AsyncListener listener)
-    {
-        synchronized(this)
-        {
-            if (_asyncListeners==null)
-                _asyncListeners=new ArrayList<AsyncListener>();
-            _asyncListeners.add(listener);
-        }
-    }
+	/* ------------------------------------------------------------ */
+	public void addListener(AsyncListener listener)
+	{
+		synchronized(this)
+		{
+			if (_asyncListeners==null)
+				_asyncListeners=new ArrayList<AsyncListener>();
+			_asyncListeners.add(listener);
+		}
+	}
 
-    /* ------------------------------------------------------------ */
-    public void addListener(AsyncListener listener,ServletRequest request, ServletResponse response)
-    {
-        synchronized(this)
-        {
-            // TODO handle the request/response ???
-            if (_asyncListeners==null)
-                _asyncListeners=new ArrayList<AsyncListener>();
-            _asyncListeners.add(listener);
-        }
-    }
+	/* ------------------------------------------------------------ */
+	public void addListener(AsyncListener listener,ServletRequest request, ServletResponse response)
+	{
+		synchronized(this)
+		{
+			// TODO handle the request/response ???
+			if (_asyncListeners==null)
+				_asyncListeners=new ArrayList<AsyncListener>();
+			_asyncListeners.add(listener);
+		}
+	}
 
-    /* ------------------------------------------------------------ */
-    public void addContinuationListener(ContinuationListener listener)
-    {
-        synchronized(this)
-        {
-            if (_continuationListeners==null)
-                _continuationListeners=new ArrayList<ContinuationListener>();
-            _continuationListeners.add(listener);
-        }
-    }
+	/* ------------------------------------------------------------ */
+	public void addContinuationListener(ContinuationListener listener)
+	{
+		synchronized(this)
+		{
+			if (_continuationListeners==null)
+				_continuationListeners=new ArrayList<ContinuationListener>();
+			_continuationListeners.add(listener);
+		}
+	}
 
-    /* ------------------------------------------------------------ */
-    public void setTimeout(long ms)
-    {
-        synchronized(this)
-        {
-            _timeoutMs=ms;
-        }
-    } 
+	/* ------------------------------------------------------------ */
+	public void setTimeout(long ms)
+	{
+		synchronized(this)
+		{
+			_timeoutMs=ms;
+		}
+	} 
 
-    /* ------------------------------------------------------------ */
-    public long getTimeout()
-    {
-        synchronized(this)
-        {
-            return _timeoutMs;
-        }
-    } 
+	/* ------------------------------------------------------------ */
+	public long getTimeout()
+	{
+		synchronized(this)
+		{
+			return _timeoutMs;
+		}
+	} 
 
-    /* ------------------------------------------------------------ */
-    public AsyncEventState getAsyncEventState()
-    {
-        synchronized(this)
-        {
-            return _event;
-        }
-    } 
+	/* ------------------------------------------------------------ */
+	public AsyncEventState getAsyncEventState()
+	{
+		synchronized(this)
+		{
+			return _event;
+		}
+	} 
    
-    /* ------------------------------------------------------------ */
-    /**
-     * @see org.eclipse.jetty.continuation.Continuation#keepWrappers()
-     */
+	/* ------------------------------------------------------------ */
+	/**
+	 * @see org.eclipse.jetty.continuation.Continuation#keepWrappers()
+	 */
 
-    /* ------------------------------------------------------------ */
-    /**
-     * @see org.eclipse.jetty.continuation.Continuation#isResponseWrapped()
-     */
-    public boolean isResponseWrapped()
-    {
-        return _responseWrapped;
-    }
+	/* ------------------------------------------------------------ */
+	/**
+	 * @see org.eclipse.jetty.continuation.Continuation#isResponseWrapped()
+	 */
+	public boolean isResponseWrapped()
+	{
+		return _responseWrapped;
+	}
 
-    /* ------------------------------------------------------------ */
-    /* (non-Javadoc)
-     * @see javax.servlet.ServletRequest#isInitial()
-     */
-    public boolean isInitial()
-    {
-        synchronized(this)
-        {
-            return _initial;
-        }
-    }
-    
-    public boolean isContinuation()
-    {
-        return _continuation;
-    }
-    
-    /* ------------------------------------------------------------ */
-    /* (non-Javadoc)
-     * @see javax.servlet.ServletRequest#isSuspended()
-     */
-    public boolean isSuspended()
-    {
-        synchronized(this)
-        {
-            switch(_state)
-            {
-                case __ASYNCSTARTED:
-                case __REDISPATCHING:
-                case __COMPLETING:
-                case __ASYNCWAIT:
-                    return true;
-                    
-                default:
-                    return false;   
-            }
-        }
-    }
-    
-    /* ------------------------------------------------------------ */
-    public boolean isSuspending()
-    {
-        synchronized(this)
-        {
-            switch(_state)
-            {
-                case __ASYNCSTARTED:
-                case __ASYNCWAIT:
-                    return true;
-                    
-                default:
-                    return false;   
-            }
-        }
-    }
-    
-    /* ------------------------------------------------------------ */
-    public boolean isDispatchable()
-    {
-        synchronized(this)
-        {
-            switch(_state)
-            {
-                case __REDISPATCH:
-                case __REDISPATCHED:
-                case __REDISPATCHING:
-                case __COMPLETING:
-                    return true;
-                    
-                default:
-                    return false;   
-            }
-        }
-    }
+	/* ------------------------------------------------------------ */
+	/* (non-Javadoc)
+	 * @see javax.servlet.ServletRequest#isInitial()
+	 */
+	public boolean isInitial()
+	{
+		synchronized(this)
+		{
+			return _initial;
+		}
+	}
+	
+	public boolean isContinuation()
+	{
+		return _continuation;
+	}
+	
+	/* ------------------------------------------------------------ */
+	/* (non-Javadoc)
+	 * @see javax.servlet.ServletRequest#isSuspended()
+	 */
+	public boolean isSuspended()
+	{
+		synchronized(this)
+		{
+			switch(_state)
+			{
+				case __ASYNCSTARTED:
+				case __REDISPATCHING:
+				case __COMPLETING:
+				case __ASYNCWAIT:
+					return true;
+					
+				default:
+					return false;   
+			}
+		}
+	}
+	
+	/* ------------------------------------------------------------ */
+	public boolean isSuspending()
+	{
+		synchronized(this)
+		{
+			switch(_state)
+			{
+				case __ASYNCSTARTED:
+				case __ASYNCWAIT:
+					return true;
+					
+				default:
+					return false;   
+			}
+		}
+	}
+	
+	/* ------------------------------------------------------------ */
+	public boolean isDispatchable()
+	{
+		synchronized(this)
+		{
+			switch(_state)
+			{
+				case __REDISPATCH:
+				case __REDISPATCHED:
+				case __REDISPATCHING:
+				case __COMPLETING:
+					return true;
+					
+				default:
+					return false;   
+			}
+		}
+	}
 
-    /* ------------------------------------------------------------ */
-    @Override
-    public String toString()
-    {
-        synchronized (this)
-        {
-            return super.toString()+"@"+getStatusString();
-        }
-    }
+	/* ------------------------------------------------------------ */
+	@Override
+	public String toString()
+	{
+		synchronized (this)
+		{
+			return super.toString()+"@"+getStatusString();
+		}
+	}
 
-    /* ------------------------------------------------------------ */
-    public String getStatusString()
-    {
-        synchronized (this)
-        {
-            return
-            ((_state==__IDLE)?"IDLE":
-                (_state==__DISPATCHED)?"DISPATCHED":
-                    (_state==__ASYNCSTARTED)?"ASYNCSTARTED":
-                        (_state==__ASYNCWAIT)?"ASYNCWAIT":
-                            (_state==__REDISPATCHING)?"REDISPATCHING":
-                                (_state==__REDISPATCH)?"REDISPATCH":
-                                    (_state==__REDISPATCHED)?"REDISPATCHED":
-                                        (_state==__COMPLETING)?"COMPLETING":
-                                            (_state==__UNCOMPLETED)?"UNCOMPLETED":
-                                                (_state==__COMPLETED)?"COMPLETE":
-                                                    ("UNKNOWN?"+_state))+
-            (_initial?",initial":"")+
-            (_resumed?",resumed":"")+
-            (_expired?",expired":"");
-        }
-    }
+	/* ------------------------------------------------------------ */
+	public String getStatusString()
+	{
+		synchronized (this)
+		{
+			return
+			((_state==__IDLE)?"IDLE":
+				(_state==__DISPATCHED)?"DISPATCHED":
+					(_state==__ASYNCSTARTED)?"ASYNCSTARTED":
+						(_state==__ASYNCWAIT)?"ASYNCWAIT":
+							(_state==__REDISPATCHING)?"REDISPATCHING":
+								(_state==__REDISPATCH)?"REDISPATCH":
+									(_state==__REDISPATCHED)?"REDISPATCHED":
+										(_state==__COMPLETING)?"COMPLETING":
+											(_state==__UNCOMPLETED)?"UNCOMPLETED":
+												(_state==__COMPLETED)?"COMPLETE":
+													("UNKNOWN?"+_state))+
+			(_initial?",initial":"")+
+			(_resumed?",resumed":"")+
+			(_expired?",expired":"");
+		}
+	}
 
-    /* ------------------------------------------------------------ */
-    /**
-     * @return false if the handling of the request should not proceed
-     */
-    protected boolean handling()
-    {
-        synchronized (this)
-        {
-            _continuation=false;
-            
-            switch(_state)
-            {
-                case __IDLE:
-                    _initial=true;
-                    _state=__DISPATCHED;
-                    if (_lastAsyncListeners!=null)
-                        _lastAsyncListeners.clear();
-                    if (_asyncListeners!=null)
-                        _asyncListeners.clear();
-                    else
-                    {
-                        _asyncListeners=_lastAsyncListeners;
-                        _lastAsyncListeners=null;
-                    }
-                    return true;
-                    
-                case __COMPLETING:
-                    _state=__UNCOMPLETED;
-                    return false;
+	/* ------------------------------------------------------------ */
+	/**
+	 * @return false if the handling of the request should not proceed
+	 */
+	protected boolean handling()
+	{
+		synchronized (this)
+		{
+			_continuation=false;
+			
+			switch(_state)
+			{
+				case __IDLE:
+					_initial=true;
+					_state=__DISPATCHED;
+					if (_lastAsyncListeners!=null)
+						_lastAsyncListeners.clear();
+					if (_asyncListeners!=null)
+						_asyncListeners.clear();
+					else
+					{
+						_asyncListeners=_lastAsyncListeners;
+						_lastAsyncListeners=null;
+					}
+					return true;
+					
+				case __COMPLETING:
+					_state=__UNCOMPLETED;
+					return false;
 
-                case __ASYNCWAIT:
-                    return false;
-                    
-                case __REDISPATCH:
-                    _state=__REDISPATCHED;
-                    return true;
+				case __ASYNCWAIT:
+					return false;
+					
+				case __REDISPATCH:
+					_state=__REDISPATCHED;
+					return true;
 
-                default:
-                    throw new IllegalStateException(this.getStatusString());
-            }
-        }
-    }
+				default:
+					throw new IllegalStateException(this.getStatusString());
+			}
+		}
+	}
 
-    /* ------------------------------------------------------------ */
-    /* (non-Javadoc)
-     * @see javax.servlet.ServletRequest#suspend(long)
-     */
-    private void doSuspend(final ServletContext context,
-            final ServletRequest request,
-            final ServletResponse response)
-    {
-        synchronized (this)
-        {
-            switch(_state)
-            {
-                case __DISPATCHED:
-                case __REDISPATCHED:
-                    _resumed=false;
-                    _expired=false;
+	/* ------------------------------------------------------------ */
+	/* (non-Javadoc)
+	 * @see javax.servlet.ServletRequest#suspend(long)
+	 */
+	private void doSuspend(final ServletContext context,
+			final ServletRequest request,
+			final ServletResponse response)
+	{
+		synchronized (this)
+		{
+			switch(_state)
+			{
+				case __DISPATCHED:
+				case __REDISPATCHED:
+					_resumed=false;
+					_expired=false;
 
-                    if (_event==null || request!=_event.getSuppliedRequest() || response != _event.getSuppliedResponse() || context != _event.getServletContext())
-                        _event=new AsyncEventState(context,request,response);
-                    else
-                    {
-                        _event._dispatchContext=null;
-                        _event._pathInContext=null;
-                    }
-                    _state=__ASYNCSTARTED;
-                    List<AsyncListener> recycle=_lastAsyncListeners;
-                    _lastAsyncListeners=_asyncListeners;
-                    _asyncListeners=recycle;
-                    if (_asyncListeners!=null)
-                        _asyncListeners.clear();
-                    break;
+					if (_event==null || request!=_event.getSuppliedRequest() || response != _event.getSuppliedResponse() || context != _event.getServletContext())
+						_event=new AsyncEventState(context,request,response);
+					else
+					{
+						_event._dispatchContext=null;
+						_event._pathInContext=null;
+					}
+					_state=__ASYNCSTARTED;
+					List<AsyncListener> recycle=_lastAsyncListeners;
+					_lastAsyncListeners=_asyncListeners;
+					_asyncListeners=recycle;
+					if (_asyncListeners!=null)
+						_asyncListeners.clear();
+					break;
 
-                default:
-                    throw new IllegalStateException(this.getStatusString());
-            }
-        }
-        
-        if (_lastAsyncListeners!=null)
-        {
-            for (AsyncListener listener : _lastAsyncListeners)
-            {
-                try
-                {
-                    listener.onStartAsync(_event);
-                }
-                catch(Exception e)
-                {
-                    LOG.warn("",e);
-                }
-            }
-        }
-    }
+				default:
+					throw new IllegalStateException(this.getStatusString());
+			}
+		}
+		
+		if (_lastAsyncListeners!=null)
+		{
+			for (AsyncListener listener : _lastAsyncListeners)
+			{
+				try
+				{
+					listener.onStartAsync(_event);
+				}
+				catch(Exception e)
+				{
+					LOG.warn("",e);
+				}
+			}
+		}
+	}
 
-    /* ------------------------------------------------------------ */
-    /**
-     * Signal that the HttpConnection has finished handling the request.
-     * For blocking connectors, this call may block if the request has
-     * been suspended (startAsync called).
-     * @return true if handling is complete, false if the request should 
-     * be handled again (eg because of a resume that happened before unhandle was called)
-     */
-    protected boolean unhandle()
-    {
-        synchronized (this)
-        {
-            switch(_state)
-            {
-                case __REDISPATCHED:
-                case __DISPATCHED:
-                    _state=__UNCOMPLETED;
-                    return true;
+	/* ------------------------------------------------------------ */
+	/**
+	 * Signal that the HttpConnection has finished handling the request.
+	 * For blocking connectors, this call may block if the request has
+	 * been suspended (startAsync called).
+	 * @return true if handling is complete, false if the request should 
+	 * be handled again (eg because of a resume that happened before unhandle was called)
+	 */
+	protected boolean unhandle()
+	{
+		synchronized (this)
+		{
+			switch(_state)
+			{
+				case __REDISPATCHED:
+				case __DISPATCHED:
+					_state=__UNCOMPLETED;
+					return true;
 
-                case __IDLE:
-                    throw new IllegalStateException(this.getStatusString());
+				case __IDLE:
+					throw new IllegalStateException(this.getStatusString());
 
-                case __ASYNCSTARTED:
-                    _initial=false;
-                    _state=__ASYNCWAIT;
-                    scheduleTimeout(); // could block and change state.
-                    if (_state==__ASYNCWAIT)
-                        return true;
-                    else if (_state==__COMPLETING)
-                    {
-                        _state=__UNCOMPLETED;
-                        return true;
-                    }         
-                    _initial=false;
-                    _state=__REDISPATCHED;
-                    return false; 
+				case __ASYNCSTARTED:
+					_initial=false;
+					_state=__ASYNCWAIT;
+					scheduleTimeout(); // could block and change state.
+					if (_state==__ASYNCWAIT)
+						return true;
+					else if (_state==__COMPLETING)
+					{
+						_state=__UNCOMPLETED;
+						return true;
+					}         
+					_initial=false;
+					_state=__REDISPATCHED;
+					return false; 
 
-                case __REDISPATCHING:
-                    _initial=false;
-                    _state=__REDISPATCHED;
-                    return false; 
+				case __REDISPATCHING:
+					_initial=false;
+					_state=__REDISPATCHED;
+					return false; 
 
-                case __COMPLETING:
-                    _initial=false;
-                    _state=__UNCOMPLETED;
-                    return true;
+				case __COMPLETING:
+					_initial=false;
+					_state=__UNCOMPLETED;
+					return true;
 
-                default:
-                    throw new IllegalStateException(this.getStatusString());
-            }
-        }
-    }
+				default:
+					throw new IllegalStateException(this.getStatusString());
+			}
+		}
+	}
 
-    /* ------------------------------------------------------------ */
-    public void dispatch()
-    {
-        boolean dispatch=false;
-        synchronized (this)
-        {
-            switch(_state)
-            {
-                case __ASYNCSTARTED:
-                    _state=__REDISPATCHING;
-                    _resumed=true;
-                    return;
+	/* ------------------------------------------------------------ */
+	public void dispatch()
+	{
+		boolean dispatch=false;
+		synchronized (this)
+		{
+			switch(_state)
+			{
+				case __ASYNCSTARTED:
+					_state=__REDISPATCHING;
+					_resumed=true;
+					return;
 
-                case __ASYNCWAIT:
-                    dispatch=!_expired;
-                    _state=__REDISPATCH;
-                    _resumed=true;
-                    break;
-                    
-                case __REDISPATCH:
-                    return;
-                    
-                default:
-                    throw new IllegalStateException(this.getStatusString());
-            }
-        }
-        
-        if (dispatch)
-        {
-            cancelTimeout();
-            scheduleDispatch();
-        }
-    }
+				case __ASYNCWAIT:
+					dispatch=!_expired;
+					_state=__REDISPATCH;
+					_resumed=true;
+					break;
+					
+				case __REDISPATCH:
+					return;
+					
+				default:
+					throw new IllegalStateException(this.getStatusString());
+			}
+		}
+		
+		if (dispatch)
+		{
+			cancelTimeout();
+			scheduleDispatch();
+		}
+	}
 
-    /* ------------------------------------------------------------ */
-    protected void expired()
-    {
-        final List<ContinuationListener> cListeners;
-        final List<AsyncListener> aListeners;
-        synchronized (this)
-        {
-            switch(_state)
-            {
-                case __ASYNCSTARTED:
-                case __ASYNCWAIT:
-                    cListeners=_continuationListeners;
-                    aListeners=_asyncListeners;
-                    break;
-                default:
-                    cListeners=null;
-                    aListeners=null;
-                    return;
-            }
-            _expired=true;
-        }
-        
-        if (aListeners!=null)
-        {
-            for (AsyncListener listener : aListeners)
-            {
-                try
-                {
-                    listener.onTimeout(_event);
-                }
-                catch(Exception e)
-                {
-                    LOG.debug("",e);
-                    _connection.getRequest().setAttribute(RequestDispatcher.ERROR_EXCEPTION,e);
-                    break;
-                }
-            }
-        }
-        if (cListeners!=null)
-        {
-            for (ContinuationListener listener : cListeners)
-            {
-                try
-                {
-                    listener.onTimeout(this);
-                }
-                catch(Exception e)
-                {
-                    LOG.warn("",e);
-                }
-            }
-        }
-        
-        synchronized (this)
-        {
-            switch(_state)
-            {
-                case __ASYNCSTARTED:
-                case __ASYNCWAIT:
-                    dispatch();
-                    break;
-                    
-                default:
-                    if (!_continuation)
-                        _expired=false;
-            }
-        }
+	/* ------------------------------------------------------------ */
+	protected void expired()
+	{
+		final List<ContinuationListener> cListeners;
+		final List<AsyncListener> aListeners;
+		synchronized (this)
+		{
+			switch(_state)
+			{
+				case __ASYNCSTARTED:
+				case __ASYNCWAIT:
+					cListeners=_continuationListeners;
+					aListeners=_asyncListeners;
+					break;
+				default:
+					cListeners=null;
+					aListeners=null;
+					return;
+			}
+			_expired=true;
+		}
+		
+		if (aListeners!=null)
+		{
+			for (AsyncListener listener : aListeners)
+			{
+				try
+				{
+					listener.onTimeout(_event);
+				}
+				catch(Exception e)
+				{
+					LOG.debug("",e);
+					_connection.getRequest().setAttribute(RequestDispatcher.ERROR_EXCEPTION,e);
+					break;
+				}
+			}
+		}
+		if (cListeners!=null)
+		{
+			for (ContinuationListener listener : cListeners)
+			{
+				try
+				{
+					listener.onTimeout(this);
+				}
+				catch(Exception e)
+				{
+					LOG.warn("",e);
+				}
+			}
+		}
+		
+		synchronized (this)
+		{
+			switch(_state)
+			{
+				case __ASYNCSTARTED:
+				case __ASYNCWAIT:
+					dispatch();
+					break;
+					
+				default:
+					if (!_continuation)
+						_expired=false;
+			}
+		}
 
-        scheduleDispatch();
-    }
-    
-    /* ------------------------------------------------------------ */
-    /* (non-Javadoc)
-     * @see javax.servlet.ServletRequest#complete()
-     */
-    public void complete()
-    {
-        // just like resume, except don't set _resumed=true;
-        boolean dispatch=false;
-        synchronized (this)
-        {
-            switch(_state)
-            {
-                case __DISPATCHED:
-                case __REDISPATCHED:
-                    throw new IllegalStateException(this.getStatusString());
+		scheduleDispatch();
+	}
+	
+	/* ------------------------------------------------------------ */
+	/* (non-Javadoc)
+	 * @see javax.servlet.ServletRequest#complete()
+	 */
+	public void complete()
+	{
+		// just like resume, except don't set _resumed=true;
+		boolean dispatch=false;
+		synchronized (this)
+		{
+			switch(_state)
+			{
+				case __DISPATCHED:
+				case __REDISPATCHED:
+					throw new IllegalStateException(this.getStatusString());
 
-                case __ASYNCSTARTED:
-                    _state=__COMPLETING;
-                    return;
-                    
-                case __ASYNCWAIT:
-                    _state=__COMPLETING;
-                    dispatch=!_expired;
-                    break;
-                    
-                default:
-                    throw new IllegalStateException(this.getStatusString());
-            }
-        }
-        
-        if (dispatch)
-        {
-            cancelTimeout();
-            scheduleDispatch();
-        }
-    }
-    
-    /* ------------------------------------------------------------ */
-    /* (non-Javadoc)
-     * @see javax.servlet.ServletRequest#complete()
-     */
-    public void errorComplete()
-    {
-        // just like complete except can overrule a prior dispatch call;
-        synchronized (this)
-        {
-            switch(_state)
-            {
-                case __REDISPATCHING:
-                case __ASYNCSTARTED:
-                    _state=__COMPLETING;
-                    _resumed=false;
-                    return;
-                    
-                case __COMPLETING:
-                    return;
-                    
-                default:
-                    throw new IllegalStateException(this.getStatusString());
-            }
-        }
-    }
+				case __ASYNCSTARTED:
+					_state=__COMPLETING;
+					return;
+					
+				case __ASYNCWAIT:
+					_state=__COMPLETING;
+					dispatch=!_expired;
+					break;
+					
+				default:
+					throw new IllegalStateException(this.getStatusString());
+			}
+		}
+		
+		if (dispatch)
+		{
+			cancelTimeout();
+			scheduleDispatch();
+		}
+	}
+	
+	/* ------------------------------------------------------------ */
+	/* (non-Javadoc)
+	 * @see javax.servlet.ServletRequest#complete()
+	 */
+	public void errorComplete()
+	{
+		// just like complete except can overrule a prior dispatch call;
+		synchronized (this)
+		{
+			switch(_state)
+			{
+				case __REDISPATCHING:
+				case __ASYNCSTARTED:
+					_state=__COMPLETING;
+					_resumed=false;
+					return;
+					
+				case __COMPLETING:
+					return;
+					
+				default:
+					throw new IllegalStateException(this.getStatusString());
+			}
+		}
+	}
 
-    /* ------------------------------------------------------------ */
-    @Override
-    public <T extends AsyncListener> T createListener(Class<T> clazz) throws ServletException 
-    {
-        try
-        {
-            // TODO inject
-            return clazz.newInstance();
-        }
-        catch(Exception e)
-        {
-            throw new ServletException(e);
-        }
-    }
+	/* ------------------------------------------------------------ */
+	@Override
+	public <T extends AsyncListener> T createListener(Class<T> clazz) throws ServletException 
+	{
+		try
+		{
+			// TODO inject
+			return clazz.newInstance();
+		}
+		catch(Exception e)
+		{
+			throw new ServletException(e);
+		}
+	}
 
 
-    /* ------------------------------------------------------------ */
-    /* (non-Javadoc)
-     * @see javax.servlet.ServletRequest#complete()
-     */
-    protected void doComplete(Throwable ex)
-    {
-        final List<ContinuationListener> cListeners;
-        final List<AsyncListener> aListeners;
-        synchronized (this)
-        {
-            switch(_state)
-            {
-                case __UNCOMPLETED:
-                    _state=__COMPLETED;
-                    cListeners=_continuationListeners;
-                    aListeners=_asyncListeners;
-                    break;
-                    
-                default:
-                    cListeners=null;
-                    aListeners=null;
-                    throw new IllegalStateException(this.getStatusString());
-            }
-        }
-        
-        if (aListeners!=null)
-        {
-            for (AsyncListener listener : aListeners)
-            {
-                try
-                {
-                    if (ex!=null)
-                    {
-                        _event.getSuppliedRequest().setAttribute(RequestDispatcher.ERROR_EXCEPTION,ex);
-                        _event.getSuppliedRequest().setAttribute(RequestDispatcher.ERROR_MESSAGE,ex.getMessage());
-                        listener.onError(_event);
-                    }
-                    else
-                        listener.onComplete(_event);
-                }
-                catch(Exception e)
-                {
-                    LOG.warn("",e);
-                }
-            }
-        }
-        if (cListeners!=null)
-        {
-            for (ContinuationListener listener : cListeners)
-            {
-                try
-                {
-                    listener.onComplete(this);
-                }
-                catch(Exception e)
-                {
-                    LOG.warn("",e);
-                }
-            }
-        }
-    }
+	/* ------------------------------------------------------------ */
+	/* (non-Javadoc)
+	 * @see javax.servlet.ServletRequest#complete()
+	 */
+	protected void doComplete(Throwable ex)
+	{
+		final List<ContinuationListener> cListeners;
+		final List<AsyncListener> aListeners;
+		synchronized (this)
+		{
+			switch(_state)
+			{
+				case __UNCOMPLETED:
+					_state=__COMPLETED;
+					cListeners=_continuationListeners;
+					aListeners=_asyncListeners;
+					break;
+					
+				default:
+					cListeners=null;
+					aListeners=null;
+					throw new IllegalStateException(this.getStatusString());
+			}
+		}
+		
+		if (aListeners!=null)
+		{
+			for (AsyncListener listener : aListeners)
+			{
+				try
+				{
+					if (ex!=null)
+					{
+						_event.getSuppliedRequest().setAttribute(RequestDispatcher.ERROR_EXCEPTION,ex);
+						_event.getSuppliedRequest().setAttribute(RequestDispatcher.ERROR_MESSAGE,ex.getMessage());
+						listener.onError(_event);
+					}
+					else
+						listener.onComplete(_event);
+				}
+				catch(Exception e)
+				{
+					LOG.warn("",e);
+				}
+			}
+		}
+		if (cListeners!=null)
+		{
+			for (ContinuationListener listener : cListeners)
+			{
+				try
+				{
+					listener.onComplete(this);
+				}
+				catch(Exception e)
+				{
+					LOG.warn("",e);
+				}
+			}
+		}
+	}
 
-    /* ------------------------------------------------------------ */
-    protected void recycle()
-    {
-        synchronized (this)
-        {
-            switch(_state)
-            {
-                case __DISPATCHED:
-                case __REDISPATCHED:
-                    throw new IllegalStateException(getStatusString());
-                default:
-                    _state=__IDLE;
-            }
-            _initial = true;
-            _resumed=false;
-            _expired=false;
-            _responseWrapped=false;
-            cancelTimeout();
-            _timeoutMs=DEFAULT_TIMEOUT;
-            _continuationListeners=null;
-        }
-    }    
-    
-    /* ------------------------------------------------------------ */
-    public void cancel()
-    {
-        synchronized (this)
-        {
-            cancelTimeout();
-            _continuationListeners=null;
-        }
-    }
+	/* ------------------------------------------------------------ */
+	protected void recycle()
+	{
+		synchronized (this)
+		{
+			switch(_state)
+			{
+				case __DISPATCHED:
+				case __REDISPATCHED:
+					throw new IllegalStateException(getStatusString());
+				default:
+					_state=__IDLE;
+			}
+			_initial = true;
+			_resumed=false;
+			_expired=false;
+			_responseWrapped=false;
+			cancelTimeout();
+			_timeoutMs=DEFAULT_TIMEOUT;
+			_continuationListeners=null;
+		}
+	}    
+	
+	/* ------------------------------------------------------------ */
+	public void cancel()
+	{
+		synchronized (this)
+		{
+			cancelTimeout();
+			_continuationListeners=null;
+		}
+	}
 
-    /* ------------------------------------------------------------ */
-    protected void scheduleDispatch()
-    {
-        EndPoint endp=_connection.getEndPoint();
-        if (!endp.isBlocking())
-        {
-            ((AsyncEndPoint)endp).asyncDispatch();
-        }
-    }
+	/* ------------------------------------------------------------ */
+	protected void scheduleDispatch()
+	{
+		EndPoint endp=_connection.getEndPoint();
+		if (!endp.isBlocking())
+		{
+			((AsyncEndPoint)endp).asyncDispatch();
+		}
+	}
 
-    /* ------------------------------------------------------------ */
-    protected void scheduleTimeout()
-    {
-        EndPoint endp=_connection.getEndPoint();
-        if (_timeoutMs>0)
-        {
-            if (endp.isBlocking())
-            {
-                synchronized(this)
-                {
-                    _expireAt = System.currentTimeMillis()+_timeoutMs;
-                    long wait=_timeoutMs;
-                    while (_expireAt>0 && wait>0 && _connection.getServer().isRunning())
-                    {
-                        try
-                        {
-                            this.wait(wait);
-                        }
-                        catch (InterruptedException e)
-                        {
-                            LOG.trace("",e);
-                        }
-                        wait=_expireAt-System.currentTimeMillis();
-                    }
+	/* ------------------------------------------------------------ */
+	protected void scheduleTimeout()
+	{
+		EndPoint endp=_connection.getEndPoint();
+		if (_timeoutMs>0)
+		{
+			if (endp.isBlocking())
+			{
+				synchronized(this)
+				{
+					_expireAt = System.currentTimeMillis()+_timeoutMs;
+					long wait=_timeoutMs;
+					while (_expireAt>0 && wait>0 && _connection.getServer().isRunning())
+					{
+						try
+						{
+							this.wait(wait);
+						}
+						catch (InterruptedException e)
+						{
+							LOG.trace("",e);
+						}
+						wait=_expireAt-System.currentTimeMillis();
+					}
 
-                    if (_expireAt>0 && wait<=0 && _connection.getServer().isRunning())
-                    {
-                        expired();
-                    }
-                }            
-            }
-            else
-            {
-                ((AsyncEndPoint)endp).scheduleTimeout(_event._timeout,_timeoutMs);
-            }
-        }
-    }
+					if (_expireAt>0 && wait<=0 && _connection.getServer().isRunning())
+					{
+						expired();
+					}
+				}            
+			}
+			else
+			{
+				((AsyncEndPoint)endp).scheduleTimeout(_event._timeout,_timeoutMs);
+			}
+		}
+	}
 
-    /* ------------------------------------------------------------ */
-    protected void cancelTimeout()
-    {
-        EndPoint endp=_connection.getEndPoint();
-        if (endp.isBlocking())
-        {
-            synchronized(this)
-            {
-                _expireAt=0;
-                this.notifyAll();
-            }
-        }
-        else 
-        {
-            final AsyncEventState event=_event;
-            if (event!=null)
-            {
-                ((AsyncEndPoint)endp).cancelTimeout(event._timeout);
-            }
-        }
-    }
+	/* ------------------------------------------------------------ */
+	protected void cancelTimeout()
+	{
+		EndPoint endp=_connection.getEndPoint();
+		if (endp.isBlocking())
+		{
+			synchronized(this)
+			{
+				_expireAt=0;
+				this.notifyAll();
+			}
+		}
+		else 
+		{
+			final AsyncEventState event=_event;
+			if (event!=null)
+			{
+				((AsyncEndPoint)endp).cancelTimeout(event._timeout);
+			}
+		}
+	}
 
-    /* ------------------------------------------------------------ */
-    public boolean isCompleting()
-    {
-        synchronized (this)
-        {
-            return _state==__COMPLETING;
-        }
-    }
-    
-    /* ------------------------------------------------------------ */
-    boolean isUncompleted()
-    {
-        synchronized (this)
-        {
-            return _state==__UNCOMPLETED;
-        }
-    } 
-    
-    /* ------------------------------------------------------------ */
-    public boolean isComplete()
-    {
-        synchronized (this)
-        {
-            return _state==__COMPLETED;
-        }
-    }
+	/* ------------------------------------------------------------ */
+	public boolean isCompleting()
+	{
+		synchronized (this)
+		{
+			return _state==__COMPLETING;
+		}
+	}
+	
+	/* ------------------------------------------------------------ */
+	boolean isUncompleted()
+	{
+		synchronized (this)
+		{
+			return _state==__UNCOMPLETED;
+		}
+	} 
+	
+	/* ------------------------------------------------------------ */
+	public boolean isComplete()
+	{
+		synchronized (this)
+		{
+			return _state==__COMPLETED;
+		}
+	}
 
 
-    /* ------------------------------------------------------------ */
-    public boolean isAsyncStarted()
-    {
-        synchronized (this)
-        {
-            switch(_state)
-            {
-                case __ASYNCSTARTED:
-                case __REDISPATCHING:
-                case __REDISPATCH:
-                case __ASYNCWAIT:
-                    return true;
+	/* ------------------------------------------------------------ */
+	public boolean isAsyncStarted()
+	{
+		synchronized (this)
+		{
+			switch(_state)
+			{
+				case __ASYNCSTARTED:
+				case __REDISPATCHING:
+				case __REDISPATCH:
+				case __ASYNCWAIT:
+					return true;
 
-                default:
-                    return false;
-            }
-        }
-    }
+				default:
+					return false;
+			}
+		}
+	}
 
 
-    /* ------------------------------------------------------------ */
-    public boolean isAsync()
-    {
-        synchronized (this)
-        {
-            switch(_state)
-            {
-                case __IDLE:
-                case __DISPATCHED:
-                case __UNCOMPLETED:
-                case __COMPLETED:
-                    return false;
+	/* ------------------------------------------------------------ */
+	public boolean isAsync()
+	{
+		synchronized (this)
+		{
+			switch(_state)
+			{
+				case __IDLE:
+				case __DISPATCHED:
+				case __UNCOMPLETED:
+				case __COMPLETED:
+					return false;
 
-                default:
-                    return true;
-            }
-        }
-    }
+				default:
+					return true;
+			}
+		}
+	}
 
-    /* ------------------------------------------------------------ */
-    public void dispatch(ServletContext context, String path)
-    {
-        _event._dispatchContext=context;
-        _event.setPath(path);
-        dispatch();
-    }
+	/* ------------------------------------------------------------ */
+	public void dispatch(ServletContext context, String path)
+	{
+		_event._dispatchContext=context;
+		_event.setPath(path);
+		dispatch();
+	}
 
-    /* ------------------------------------------------------------ */
-    public void dispatch(String path)
-    {
-        _event.setPath(path);
-        dispatch();
-    }
+	/* ------------------------------------------------------------ */
+	public void dispatch(String path)
+	{
+		_event.setPath(path);
+		dispatch();
+	}
 
-    /* ------------------------------------------------------------ */
-    public Request getBaseRequest()
-    {
-        return _connection.getRequest();
-    }
-    
-    /* ------------------------------------------------------------ */
-    public ServletRequest getRequest()
-    {
-        if (_event!=null)
-            return _event.getSuppliedRequest();
-        return _connection.getRequest();
-    }
+	/* ------------------------------------------------------------ */
+	public Request getBaseRequest()
+	{
+		return _connection.getRequest();
+	}
+	
+	/* ------------------------------------------------------------ */
+	public ServletRequest getRequest()
+	{
+		if (_event!=null)
+			return _event.getSuppliedRequest();
+		return _connection.getRequest();
+	}
 
-    /* ------------------------------------------------------------ */
-    public ServletResponse getResponse()
-    {
-        if (_responseWrapped && _event!=null && _event.getSuppliedResponse()!=null)
-            return _event.getSuppliedResponse();
-        return _connection.getResponse();
-    }
+	/* ------------------------------------------------------------ */
+	public ServletResponse getResponse()
+	{
+		if (_responseWrapped && _event!=null && _event.getSuppliedResponse()!=null)
+			return _event.getSuppliedResponse();
+		return _connection.getResponse();
+	}
 
-    /* ------------------------------------------------------------ */
-    public void start(final Runnable run)
-    {
-        final AsyncEventState event=_event;
-        if (event!=null)
-        {
-            _connection.getServer().getThreadPool().dispatch(new Runnable()
-            {
-                public void run()
-                {
-                    ((Context)event.getServletContext()).getContextHandler().handle(run);
-                }
-            });
-        }
-    }
+	/* ------------------------------------------------------------ */
+	public void start(final Runnable run)
+	{
+		final AsyncEventState event=_event;
+		if (event!=null)
+		{
+			_connection.getServer().getThreadPool().execute(new Runnable()
+			{
+				public void run()
+				{
+					((Context)event.getServletContext()).getContextHandler().handle(run);
+				}
+			});
+		}
+	}
 
-    /* ------------------------------------------------------------ */
-    public boolean hasOriginalRequestAndResponse()
-    {
-        synchronized (this)
-        {
-            return (_event!=null && _event.getSuppliedRequest()==_connection._request && _event.getSuppliedResponse()==_connection._response);
-        }
-    }
+	/* ------------------------------------------------------------ */
+	public boolean hasOriginalRequestAndResponse()
+	{
+		synchronized (this)
+		{
+			return (_event!=null && _event.getSuppliedRequest()==_connection._request && _event.getSuppliedResponse()==_connection._response);
+		}
+	}
 
-    /* ------------------------------------------------------------ */
-    public ContextHandler getContextHandler()
-    {
-        final AsyncEventState event=_event;
-        if (event!=null)
-            return ((Context)event.getServletContext()).getContextHandler();
-        return null;
-    }
+	/* ------------------------------------------------------------ */
+	public ContextHandler getContextHandler()
+	{
+		final AsyncEventState event=_event;
+		if (event!=null)
+			return ((Context)event.getServletContext()).getContextHandler();
+		return null;
+	}
 
 
-    /* ------------------------------------------------------------ */
-    /**
-     * @see Continuation#isResumed()
-     */
-    public boolean isResumed()
-    {
-        synchronized (this)
-        {
-            return _resumed;
-        }
-    }
-    /* ------------------------------------------------------------ */
-    /**
-     * @see Continuation#isExpired()
-     */
-    public boolean isExpired()
-    {
-        synchronized (this)
-        {
-            return _expired;
-        }
-    }
+	/* ------------------------------------------------------------ */
+	/**
+	 * @see Continuation#isResumed()
+	 */
+	public boolean isResumed()
+	{
+		synchronized (this)
+		{
+			return _resumed;
+		}
+	}
+	/* ------------------------------------------------------------ */
+	/**
+	 * @see Continuation#isExpired()
+	 */
+	public boolean isExpired()
+	{
+		synchronized (this)
+		{
+			return _expired;
+		}
+	}
 
-    /* ------------------------------------------------------------ */
-    /**
-     * @see Continuation#resume()
-     */
-    public void resume()
-    {
-        dispatch();
-    }
-    
+	/* ------------------------------------------------------------ */
+	/**
+	 * @see Continuation#resume()
+	 */
+	public void resume()
+	{
+		dispatch();
+	}
+	
 
 
-    /* ------------------------------------------------------------ */
-    protected void startAsync(final ServletContext context,
-            final ServletRequest request,
-            final ServletResponse response)
-    {
-        synchronized (this)
-        {
-            _responseWrapped=!(response instanceof Response);
-            doSuspend(context,request,response);
-            if (request instanceof HttpServletRequest)
-            {
-                _event._pathInContext = URIUtil.addPaths(((HttpServletRequest)request).getServletPath(),((HttpServletRequest)request).getPathInfo());
-            }
-        }
-    }
+	/* ------------------------------------------------------------ */
+	protected void startAsync(final ServletContext context,
+			final ServletRequest request,
+			final ServletResponse response)
+	{
+		synchronized (this)
+		{
+			_responseWrapped=!(response instanceof Response);
+			doSuspend(context,request,response);
+			if (request instanceof HttpServletRequest)
+			{
+				_event._pathInContext = URIUtil.addPaths(((HttpServletRequest)request).getServletPath(),((HttpServletRequest)request).getPathInfo());
+			}
+		}
+	}
 
-    /* ------------------------------------------------------------ */
-    protected void startAsync()
-    {
-        _responseWrapped=false;
-        _continuation=false;
-        doSuspend(_connection.getRequest().getServletContext(),_connection.getRequest(),_connection.getResponse());  
-    }
+	/* ------------------------------------------------------------ */
+	protected void startAsync()
+	{
+		_responseWrapped=false;
+		_continuation=false;
+		doSuspend(_connection.getRequest().getServletContext(),_connection.getRequest(),_connection.getResponse());  
+	}
 
-    
-    /* ------------------------------------------------------------ */
-    /**
-     * @see Continuation#suspend()
-     */
-    public void suspend(ServletResponse response)
-    {
-        _continuation=true;
-        _responseWrapped=!(response instanceof Response);
-        doSuspend(_connection.getRequest().getServletContext(),_connection.getRequest(),response); 
-    }
+	
+	/* ------------------------------------------------------------ */
+	/**
+	 * @see Continuation#suspend()
+	 */
+	public void suspend(ServletResponse response)
+	{
+		_continuation=true;
+		_responseWrapped=!(response instanceof Response);
+		doSuspend(_connection.getRequest().getServletContext(),_connection.getRequest(),response); 
+	}
 
-    /* ------------------------------------------------------------ */
-    /**
-     * @see Continuation#suspend()
-     */
-    public void suspend()
-    {
-        _responseWrapped=false;
-        _continuation=true;
-        doSuspend(_connection.getRequest().getServletContext(),_connection.getRequest(),_connection.getResponse());       
-    }
+	/* ------------------------------------------------------------ */
+	/**
+	 * @see Continuation#suspend()
+	 */
+	public void suspend()
+	{
+		_responseWrapped=false;
+		_continuation=true;
+		doSuspend(_connection.getRequest().getServletContext(),_connection.getRequest(),_connection.getResponse());       
+	}
 
-    /* ------------------------------------------------------------ */
-    /**
-     * @see org.eclipse.jetty.continuation.Continuation#getServletResponse()
-     */
-    public ServletResponse getServletResponse()
-    {
-        if (_responseWrapped && _event!=null && _event.getSuppliedResponse()!=null)
-            return _event.getSuppliedResponse();
-        return _connection.getResponse();
-    }
+	/* ------------------------------------------------------------ */
+	/**
+	 * @see org.eclipse.jetty.continuation.Continuation#getServletResponse()
+	 */
+	public ServletResponse getServletResponse()
+	{
+		if (_responseWrapped && _event!=null && _event.getSuppliedResponse()!=null)
+			return _event.getSuppliedResponse();
+		return _connection.getResponse();
+	}
 
-    /* ------------------------------------------------------------ */
-    /**
-     * @see org.eclipse.jetty.continuation.Continuation#getAttribute(java.lang.String)
-     */
-    public Object getAttribute(String name)
-    {
-        return _connection.getRequest().getAttribute(name);
-    }
+	/* ------------------------------------------------------------ */
+	/**
+	 * @see org.eclipse.jetty.continuation.Continuation#getAttribute(java.lang.String)
+	 */
+	public Object getAttribute(String name)
+	{
+		return _connection.getRequest().getAttribute(name);
+	}
 
-    /* ------------------------------------------------------------ */
-    /**
-     * @see org.eclipse.jetty.continuation.Continuation#removeAttribute(java.lang.String)
-     */
-    public void removeAttribute(String name)
-    {
-        _connection.getRequest().removeAttribute(name);
-    }
+	/* ------------------------------------------------------------ */
+	/**
+	 * @see org.eclipse.jetty.continuation.Continuation#removeAttribute(java.lang.String)
+	 */
+	public void removeAttribute(String name)
+	{
+		_connection.getRequest().removeAttribute(name);
+	}
 
-    /* ------------------------------------------------------------ */
-    /**
-     * @see org.eclipse.jetty.continuation.Continuation#setAttribute(java.lang.String, java.lang.Object)
-     */
-    public void setAttribute(String name, Object attribute)
-    {
-        _connection.getRequest().setAttribute(name,attribute);
-    }
+	/* ------------------------------------------------------------ */
+	/**
+	 * @see org.eclipse.jetty.continuation.Continuation#setAttribute(java.lang.String, java.lang.Object)
+	 */
+	public void setAttribute(String name, Object attribute)
+	{
+		_connection.getRequest().setAttribute(name,attribute);
+	}
 
-    /* ------------------------------------------------------------ */
-    /**
-     * @see org.eclipse.jetty.continuation.Continuation#undispatch()
-     */
-    public void undispatch()
-    {
-        if (isSuspended())
-        {
-            if (LOG.isDebugEnabled())
-                throw new ContinuationThrowable();
-            else
-                throw __exception;
-        }
-        throw new IllegalStateException("!suspended");
-    }
+	/* ------------------------------------------------------------ */
+	/**
+	 * @see org.eclipse.jetty.continuation.Continuation#undispatch()
+	 */
+	public void undispatch()
+	{
+		if (isSuspended())
+		{
+			if (LOG.isDebugEnabled())
+				throw new ContinuationThrowable();
+			else
+				throw __exception;
+		}
+		throw new IllegalStateException("!suspended");
+	}
 
-    /* ------------------------------------------------------------ */
-    /* ------------------------------------------------------------ */
-    public class AsyncTimeout extends Timeout.Task implements Runnable
-    {
-            @Override
-            public void expired()
-            {
-                AsyncContinuation.this.expired();
-            }
+	/* ------------------------------------------------------------ */
+	/* ------------------------------------------------------------ */
+	public class AsyncTimeout extends Timeout.Task implements Runnable
+	{
+			@Override
+			public void expired()
+			{
+				AsyncContinuation.this.expired();
+			}
 
-            @Override
-            public void run()
-            {
-                AsyncContinuation.this.expired();
-            }
-    }
+			@Override
+			public void run()
+			{
+				AsyncContinuation.this.expired();
+			}
+	}
 
-    /* ------------------------------------------------------------ */
-    /* ------------------------------------------------------------ */
-    public class AsyncEventState extends AsyncEvent
-    {
-        private final ServletContext _suspendedContext;
-        private ServletContext _dispatchContext;
-        private String _pathInContext;
-        private Timeout.Task _timeout=  new AsyncTimeout();
-        
-        public AsyncEventState(ServletContext context, ServletRequest request, ServletResponse response)
-        {
-            super(AsyncContinuation.this, request,response);
-            _suspendedContext=context;
-            // Get the base request So we can remember the initial paths
-            Request r=_connection.getRequest();
+	/* ------------------------------------------------------------ */
+	/* ------------------------------------------------------------ */
+	public class AsyncEventState extends AsyncEvent
+	{
+		private final ServletContext _suspendedContext;
+		private ServletContext _dispatchContext;
+		private String _pathInContext;
+		private Timeout.Task _timeout=  new AsyncTimeout();
+		
+		public AsyncEventState(ServletContext context, ServletRequest request, ServletResponse response)
+		{
+			super(AsyncContinuation.this, request,response);
+			_suspendedContext=context;
+			// Get the base request So we can remember the initial paths
+			Request r=_connection.getRequest();
  
-            // If we haven't been async dispatched before
-            if (r.getAttribute(AsyncContext.ASYNC_REQUEST_URI)==null)
-            {
-                // We are setting these attributes during startAsync, when the spec implies that 
-                // they are only available after a call to AsyncContext.dispatch(...);
-                
-                // have we been forwarded before?
-                String uri=(String)r.getAttribute(RequestDispatcher.FORWARD_REQUEST_URI);
-                if (uri!=null)
-                {
-                    r.setAttribute(AsyncContext.ASYNC_REQUEST_URI,uri);
-                    r.setAttribute(AsyncContext.ASYNC_CONTEXT_PATH,r.getAttribute(RequestDispatcher.FORWARD_CONTEXT_PATH));
-                    r.setAttribute(AsyncContext.ASYNC_SERVLET_PATH,r.getAttribute(RequestDispatcher.FORWARD_SERVLET_PATH));
-                    r.setAttribute(AsyncContext.ASYNC_PATH_INFO,r.getAttribute(RequestDispatcher.FORWARD_PATH_INFO));
-                    r.setAttribute(AsyncContext.ASYNC_QUERY_STRING,r.getAttribute(RequestDispatcher.FORWARD_QUERY_STRING));
-                }
-                else
-                {
-                    r.setAttribute(AsyncContext.ASYNC_REQUEST_URI,r.getRequestURI());
-                    r.setAttribute(AsyncContext.ASYNC_CONTEXT_PATH,r.getContextPath());
-                    r.setAttribute(AsyncContext.ASYNC_SERVLET_PATH,r.getServletPath());
-                    r.setAttribute(AsyncContext.ASYNC_PATH_INFO,r.getPathInfo());
-                    r.setAttribute(AsyncContext.ASYNC_QUERY_STRING,r.getQueryString());
-                }
-            }
-        }
-        
-        public ServletContext getSuspendedContext()
-        {
-            return _suspendedContext;
-        }
-        
-        public ServletContext getDispatchContext()
-        {
-            return _dispatchContext;
-        }
-        
-        public ServletContext getServletContext()
-        {
-            return _dispatchContext==null?_suspendedContext:_dispatchContext;
-        }
-        
-        public void setPath(String path)
-        {
-            _pathInContext=path;
-        }
-        
-        /* ------------------------------------------------------------ */
-        /**
-         * @return The path in the context
-         */
-        public String getPath()
-        {
-            return _pathInContext;
-        }
-    }
+			// If we haven't been async dispatched before
+			if (r.getAttribute(AsyncContext.ASYNC_REQUEST_URI)==null)
+			{
+				// We are setting these attributes during startAsync, when the spec implies that 
+				// they are only available after a call to AsyncContext.dispatch(...);
+				
+				// have we been forwarded before?
+				String uri=(String)r.getAttribute(RequestDispatcher.FORWARD_REQUEST_URI);
+				if (uri!=null)
+				{
+					r.setAttribute(AsyncContext.ASYNC_REQUEST_URI,uri);
+					r.setAttribute(AsyncContext.ASYNC_CONTEXT_PATH,r.getAttribute(RequestDispatcher.FORWARD_CONTEXT_PATH));
+					r.setAttribute(AsyncContext.ASYNC_SERVLET_PATH,r.getAttribute(RequestDispatcher.FORWARD_SERVLET_PATH));
+					r.setAttribute(AsyncContext.ASYNC_PATH_INFO,r.getAttribute(RequestDispatcher.FORWARD_PATH_INFO));
+					r.setAttribute(AsyncContext.ASYNC_QUERY_STRING,r.getAttribute(RequestDispatcher.FORWARD_QUERY_STRING));
+				}
+				else
+				{
+					r.setAttribute(AsyncContext.ASYNC_REQUEST_URI,r.getRequestURI());
+					r.setAttribute(AsyncContext.ASYNC_CONTEXT_PATH,r.getContextPath());
+					r.setAttribute(AsyncContext.ASYNC_SERVLET_PATH,r.getServletPath());
+					r.setAttribute(AsyncContext.ASYNC_PATH_INFO,r.getPathInfo());
+					r.setAttribute(AsyncContext.ASYNC_QUERY_STRING,r.getQueryString());
+				}
+			}
+		}
+		
+		public ServletContext getSuspendedContext()
+		{
+			return _suspendedContext;
+		}
+		
+		public ServletContext getDispatchContext()
+		{
+			return _dispatchContext;
+		}
+		
+		public ServletContext getServletContext()
+		{
+			return _dispatchContext==null?_suspendedContext:_dispatchContext;
+		}
+		
+		public void setPath(String path)
+		{
+			_pathInContext=path;
+		}
+		
+		/* ------------------------------------------------------------ */
+		/**
+		 * @return The path in the context
+		 */
+		public String getPath()
+		{
+			return _pathInContext;
+		}
+	}
 }