private void detectEncoding( char[] cbuf, int off, int len )
    throws IOException
    {
        int size = len;
        StringBuffer xmlProlog = xmlPrologWriter.getBuffer();
        if ( xmlProlog.length() + len > BUFFER_SIZE )
        {
            size = BUFFER_SIZE - xmlProlog.length();
        }
        xmlPrologWriter.write( cbuf, off, size );

        // try to determine encoding
        if ( xmlProlog.length() >= 5 )
        {
            if ( xmlProlog.substring( 0, 5 ).equals( "<?xml" ) )
            {
                // try to extract encoding from XML prolog
                int xmlPrologEnd = xmlProlog.indexOf( "?>" );
                if ( xmlPrologEnd > 0 )
                {
                    // ok, full XML prolog written: let's extract encoding
                    Matcher m = ENCODING_PATTERN.matcher( xmlProlog.substring( 0, xmlPrologEnd ) );
                    if ( m.find() )
                    {
                        encoding = m.group( 1 ).toUpperCase( Locale.ENGLISH );
                        encoding = encoding.substring( 1, encoding.length() - 1 );
                    }
                    else
                    {
                        // no encoding found in XML prolog: using default encoding
                        encoding = "UTF-8";
                    }
                }
                else
                {
                    if ( xmlProlog.length() >= BUFFER_SIZE )
                    {
                        // no encoding found in first characters: using default encoding
                        encoding = "UTF-8";
                    }
                }
            }
            else
            {
                // no XML prolog: using default encoding
                encoding = "UTF-8";
            }
            if ( encoding != null )
            {
                // encoding has been chosen: let's do it
                xmlPrologWriter = null;
                writer = new OutputStreamWriter( out, encoding );
                writer.write( xmlProlog.toString() );
                if ( len > size )
                {
                    writer.write( cbuf, off + size, len - size );
                }
            }
        }
    }