        protected WhatToDo handleRead( ByteBuffer buf , Connection conn ){
            if ( _state == State.WAITING || _state == State.IN_HEADER ){
                if ( _line == null )
                    _line = new StringBuilder();
                while ( buf.hasRemaining() ){
                    char c = (char)buf.get();
                    if ( c == '\r' )
                        continue;
                    if ( c == '\n' ){
                        if ( _line.length() == 0 ){
                            _logger.debug( 3 , "end of header" );
                            _state = State.READY_TO_STREAM;
                            break;
                        }
                        String line = _line.toString();                        
                        if ( _state == State.WAITING ){
                            int idx = line.indexOf( " " );
                            if ( idx < 0 ){
                                backendError( ServerErrorType.INVALID , "invalid first line [" + line + "]" );
                                return WhatToDo.ERROR;
                            }
                            line = line.substring( idx + 1 ).trim();
                            idx = line.indexOf( " " );
                            if ( idx < 0 )
                                _response.setResponseCode( Integer.parseInt( line ) );
                            else
                                _response.setStatus( Integer.parseInt( line.substring( 0 , idx ) ) , line.substring( idx + 1 ).trim() );
                            _logger.debug( 3 , "got first line " , line );
                            _state = State.IN_HEADER;
                        }
                        else {
                            int idx = line.indexOf( ":" );
                            if ( idx < 0 ){
                                backendError( ServerErrorType.INVALID , "invalid line [ " + line + "]" );
                                return WhatToDo.ERROR;
                            }
                            String name = line.substring( 0 , idx );
                            String value = line.substring( idx + 1 ).trim();
                            _logger.debug( 3 , "got header line " , line );
                            if ( name.equalsIgnoreCase( "Connection" ) ){
                                _keepalive = ! value.toLowerCase().contains( "close" );
                            }
                            else {
                                _response.setHeader( name , value );
                            }
                        }
                        _line.setLength( 0 );
                        continue;
                    }
                    _line.append( c );
                }
                if ( _state != State.READY_TO_STREAM )
                    return WhatToDo.CONTINUE;
                _logger.debug( 3 , "starting to stream data" );
            }
            if ( _state == State.READY_TO_STREAM ){
                MyChunk chunk = new MyChunk( this , conn , _response.getContentLength() , buf );
                _response.sendFile( new MySender( chunk ) );
                _state = State.STREAMING;
            }
            try {
                _response.done();
            }
            catch ( IOException ioe ){
                _logger.debug( 2 , "client error" , ioe );
                return WhatToDo.ERROR;
            }
            return WhatToDo.PAUSE;
        }

        protected WhatToDo handleRead( ByteBuffer buf , Connection conn ){
            if ( _state == State.WAITING || _state == State.IN_HEADER ){
                if ( _line == null )
                    _line = new StringBuilder();
                while ( buf.hasRemaining() ){
                    char c = (char)buf.get();
                    if ( c == '\r' )
                        continue;
                    if ( c == '\n' ){
                        if ( _line.length() == 0 ){
                            _logger.debug( 3 , "end of header" );
                            _state = State.READY_TO_STREAM;
                            break;
                        }
                        String line = _line.toString();                        
                        if ( _state == State.WAITING ){
                            int idx = line.indexOf( " " );
                            if ( idx < 0 ){
                                backendError( ServerErrorType.INVALID , "invalid first line [" + line + "]" );
                                return WhatToDo.ERROR;
                            }
                            line = line.substring( idx + 1 ).trim();
                            idx = line.indexOf( " " );
                            if ( idx < 0 )
                                _response.setResponseCode( Integer.parseInt( line ) );
                            else
                                _response.setStatus( Integer.parseInt( line.substring( 0 , idx ) ) , line.substring( idx + 1 ).trim() );
                            _logger.debug( 3 , "got first line " , line );
                            _state = State.IN_HEADER;
                        }
                        else {
                            int idx = line.indexOf( ":" );
                            if ( idx < 0 ){
                                backendError( ServerErrorType.INVALID , "invalid line [ " + line + "]" );
                                return WhatToDo.ERROR;
                            }
                            String name = line.substring( 0 , idx );
                            String value = line.substring( idx + 1 ).trim();
                            _logger.debug( 3 , "got header line " , line );
                            if ( name.equalsIgnoreCase( "Connection" ) ){
                                _keepalive = ! value.toLowerCase().contains( "close" );
                            }
                            else {
                                _response.addHeader( name , value );
                            }
                        }
                        _line.setLength( 0 );
                        continue;
                    }
                    _line.append( c );
                }
                if ( _state != State.READY_TO_STREAM )
                    return WhatToDo.CONTINUE;
                _logger.debug( 3 , "starting to stream data" );
            }
            if ( _state == State.READY_TO_STREAM ){
                MyChunk chunk = new MyChunk( this , conn , _response.getContentLength() , buf );
                _response.sendFile( new MySender( chunk ) );
                _state = State.STREAMING;
            }
            try {
                _response.done();
            }
            catch ( IOException ioe ){
                _logger.debug( 2 , "client error" , ioe );
                return WhatToDo.ERROR;
            }
            return WhatToDo.PAUSE;
        }
