diff --git a/webconsole/src/main/java/org/apache/felix/webconsole/internal/misc/ConfigurationPrinterAdapter.java b/webconsole/src/main/java/org/apache/felix/webconsole/internal/misc/ConfigurationPrinterAdapter.java
deleted file mode 100644
index fecafe0..0000000
--- a/webconsole/src/main/java/org/apache/felix/webconsole/internal/misc/ConfigurationPrinterAdapter.java
+++ /dev/null
@@ -1,290 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.felix.webconsole.internal.misc;
-
-import java.io.PrintWriter;
-import java.lang.reflect.Method;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.felix.webconsole.*;
-import org.osgi.framework.ServiceReference;
-
-/**
- * Helper class for a configuration printer.
- */
-public class ConfigurationPrinterAdapter
-{
-
-    private final Object printer;
-    public String title;
-    public String label;
-    private final String[] modes;
-    private final boolean escapeHtml;
-    private Method modeAwarePrintMethod;
-    private Method printMethod;
-    private Method attachmentMethod;
-    private boolean checkedAttachmentMethod = false;
-
-    private static final List CUSTOM_MODES = new ArrayList();
-    static
-    {
-        CUSTOM_MODES.add( ConfigurationPrinter.MODE_TXT );
-        CUSTOM_MODES.add( ConfigurationPrinter.MODE_WEB );
-        CUSTOM_MODES.add( ConfigurationPrinter.MODE_ZIP );
-    }
-
-    public static ConfigurationPrinterAdapter createAdapter(
-            final Object service,
-            final ServiceReference ref)
-    {
-        String title;
-        Object cfgPrinter = null;
-        Object modes = null;
-        Method printMethod = null;
-        if ( service instanceof ConfigurationPrinter )
-        {
-            modes = ref.getProperty(WebConsoleConstants.CONFIG_PRINTER_MODES);
-            if ( modes == null )
-            {
-                modes = ref.getProperty( ConfigurationPrinter.PROPERTY_MODES );
-            }
-            cfgPrinter = service;
-            title = ((ConfigurationPrinter) service).getTitle();
-        }
-        else
-        {
-            modes = ref.getProperty( WebConsoleConstants.CONFIG_PRINTER_MODES );
-            title = (String)ref.getProperty(  WebConsoleConstants.PLUGIN_TITLE );
-
-            // first: printConfiguration(PrintWriter, String)
-            final Method method2Params = searchMethod(service, "printConfiguration",
-                    new Class[] {PrintWriter.class, String.class});
-            if ( method2Params != null )
-            {
-                cfgPrinter = service;
-                printMethod = method2Params;
-            }
-
-            if ( cfgPrinter == null )
-            {
-                // second: printConfiguration(PrintWriter)
-                final Method method1Params = searchMethod(service, "printConfiguration",
-                        new Class[] {PrintWriter.class});
-                if ( method1Params != null )
-                {
-                    cfgPrinter = service;
-                    printMethod = method1Params;
-                }
-            }
-        }
-        if ( cfgPrinter != null )
-        {
-            Object label =  ref.getProperty( WebConsoleConstants.PLUGIN_LABEL);
-            boolean webUnescaped;
-            Object ehObj = ref.getProperty( WebConsoleConstants.CONFIG_PRINTER_WEB_UNESCAPED );
-            if ( ehObj instanceof Boolean )
-            {
-                webUnescaped = ( ( Boolean ) ehObj ).booleanValue();
-            }
-            else if ( ehObj instanceof String )
-            {
-                webUnescaped = Boolean.valueOf( ( String ) ehObj ).booleanValue();
-            }
-            else
-            {
-                webUnescaped = false;
-            }
-            return new ConfigurationPrinterAdapter(
-                    cfgPrinter,
-                    printMethod,
-                    title,
-                    (label instanceof String ? (String)label : null),
-                    modes,
-                    !webUnescaped);
-        }
-        return null;
-    }
-
-    private ConfigurationPrinterAdapter( final Object printer,
-            final Method printMethod,
-            final String title,
-            final String label,
-            final Object modes,
-            final boolean escapeHtml )
-    {
-        this.printer = printer;
-        this.title = title;
-        this.label = label;
-        this.escapeHtml = escapeHtml;
-        if ( printMethod != null )
-        {
-            if ( printMethod.getParameterTypes().length > 1 )
-            {
-                this.modeAwarePrintMethod = printMethod;
-            }
-            else
-            {
-                this.printMethod = printMethod;
-            }
-        }
-        if ( modes == null || !( modes instanceof String || modes instanceof String[] ) )
-        {
-            this.modes = null;
-        }
-        else
-        {
-            if ( modes instanceof String )
-            {
-                if ( CUSTOM_MODES.contains(modes) )
-                {
-                    this.modes = new String[] {modes.toString()};
-                }
-                else
-                {
-                    this.modes = null;
-                }
-            }
-            else
-            {
-                final String[] values = (String[])modes;
-                boolean valid = values.length > 0;
-                for(int i=0; i<values.length; i++)
-                {
-                    if ( !CUSTOM_MODES.contains(values[i]) )
-                    {
-                        valid = false;
-                        break;
-                    }
-                }
-                if ( valid)
-                {
-                    this.modes = values;
-                }
-                else
-                {
-                    this.modes = null;
-                }
-            }
-        }
-    }
-
-    public boolean match(final String mode)
-    {
-        if ( this.modes == null)
-        {
-            return true;
-        }
-        for(int i=0; i<this.modes.length; i++)
-        {
-            if ( this.modes[i].equals(mode) )
-            {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    public boolean escapeHtml()
-    {
-        return escapeHtml;
-    }
-
-    public final void printConfiguration( final PrintWriter pw,
-            final String mode )
-    {
-        if ( printer instanceof ModeAwareConfigurationPrinter )
-        {
-            ( ( ModeAwareConfigurationPrinter ) printer ).printConfiguration( pw, mode );
-        }
-        else if ( printer instanceof ConfigurationPrinter )
-        {
-            ( ( ConfigurationPrinter ) printer ).printConfiguration( pw );
-        }
-        else if ( this.modeAwarePrintMethod != null )
-        {
-            this.invoke(this.modeAwarePrintMethod, new Object[] {pw, mode});
-        } else if ( this.printMethod != null )
-        {
-            this.invoke(this.printMethod, new Object[] {pw});
-        }
-    }
-
-    public URL[] getAttachments( final String mode )
-    {
-        // check if printer implements binary configuration printer
-        URL[] attachments = null;
-        if ( printer instanceof AttachmentProvider )
-        {
-            attachments = ((AttachmentProvider)printer).getAttachments(mode);
-        }
-        else
-        {
-            if ( !checkedAttachmentMethod )
-            {
-                attachmentMethod = searchMethod(printer, "getAttachments", new Class[] {String.class});
-                checkedAttachmentMethod = true;
-            }
-            if ( attachmentMethod != null )
-            {
-                attachments = (URL[])invoke(attachmentMethod, new Object[] {mode});
-            }
-        }
-        return attachments;
-    }
-
-    /**
-     * @see java.lang.Object#toString()
-     */
-    public String toString() {
-        return title + " (" + printer.getClass() + ")";
-    }
-
-    /**
-     * Search a method with the given name and signature
-     */
-    private static Method searchMethod(final Object obj, final String mName, final Class[] params)
-    {
-        try
-        {
-            return obj.getClass().getDeclaredMethod(mName, params);
-        }
-        catch (Throwable nsme)
-        {
-            // ignore, we catch Throwable above to not only catch NoSuchMethodException
-            // but also other ones like ClassDefNotFoundError etc.
-        }
-        return null;
-    }
-
-    /**
-     * Invoke the method on the printer with the arguments.
-     */
-    protected Object invoke(final Method m, final Object[] args)
-    {
-        try
-        {
-            return m.invoke(printer, args);
-        }
-        catch (Throwable e)
-        {
-            // ignore
-        }
-        return null;
-    }
-}
diff --git a/webconsole/src/main/java/org/apache/felix/webconsole/internal/misc/ConfigurationRender.java b/webconsole/src/main/java/org/apache/felix/webconsole/internal/misc/ConfigurationRender.java
index 5797fe9..ac3aed4 100644
--- a/webconsole/src/main/java/org/apache/felix/webconsole/internal/misc/ConfigurationRender.java
+++ b/webconsole/src/main/java/org/apache/felix/webconsole/internal/misc/ConfigurationRender.java
@@ -17,386 +17,14 @@
 package org.apache.felix.webconsole.internal.misc;
 
 
-import java.io.*;
-import java.net.URL;
-import java.net.URLEncoder;
-import java.text.DateFormat;
-import java.text.MessageFormat;
-import java.util.*;
-import java.util.zip.*;
+import java.io.PrintWriter;
 
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.apache.commons.io.IOUtils;
-import org.apache.felix.webconsole.*;
-import org.apache.felix.webconsole.internal.OsgiManagerPlugin;
-import org.apache.felix.webconsole.internal.i18n.ResourceBundleManager;
-import org.osgi.framework.*;
-import org.osgi.util.tracker.ServiceTracker;
+import org.apache.felix.webconsole.WebConsoleUtil;
 
 
-/**
- * ConfigurationRender plugin renders the configuration status - a textual
- * representation of the current framework status. The content itself is
- *  internally generated by the {@link ConfigurationPrinter} plugins.
- */
-public class ConfigurationRender extends SimpleWebConsolePlugin implements OsgiManagerPlugin
+public class ConfigurationRender
 {
 
-    private static final String LABEL = "config";
-    private static final String TITLE = "%configStatus.pluginTitle";
-    private static final String[] CSS_REFS = { "/res/ui/configurationrender.css" };
-
-    // use English as the locale for all non-display titles
-    private static final Locale DEFAULT = Locale.ENGLISH;
-
-    /**
-     * Formatter pattern to render the current time of status generation.
-     */
-    private static final DateFormat DISPLAY_DATE_FORMAT = DateFormat.getDateTimeInstance( DateFormat.LONG,
-        DateFormat.LONG, Locale.US );
-
-    /**
-     * The resource bundle manager to allow for status printer title
-     * localization
-     */
-    private final ResourceBundleManager resourceBundleManager;
-
-    private ServiceTracker cfgPrinterTracker;
-
-    private int cfgPrinterTrackerCount;
-
-    private ArrayList configurationPrinters;
-
-    /** Default constructor */
-    public ConfigurationRender( final ResourceBundleManager resourceBundleManager )
-    {
-        super( LABEL, TITLE, CATEGORY_OSGI_MANAGER, CSS_REFS );
-        this.resourceBundleManager = resourceBundleManager;
-    }
-
-
-    /**
-     * @see org.apache.felix.webconsole.SimpleWebConsolePlugin#deactivate()
-     */
-    public void deactivate()
-    {
-        // make sure the service tracker is closed and removed on deactivate
-        ServiceTracker oldTracker = cfgPrinterTracker;
-        if ( oldTracker != null )
-        {
-            oldTracker.close();
-        }
-        cfgPrinterTracker = null;
-        configurationPrinters = null;
-
-        super.deactivate();
-    }
-
-    /**
-     * Returns the requested printer name if the current request contains one
-     */
-    private String getRequestedPrinterName(final HttpServletRequest request)
-    {
-        String name = request.getPathInfo();
-        final int dotPos = name.lastIndexOf('.');
-        if ( dotPos != -1 )
-        {
-            name = name.substring(0, dotPos);
-        }
-        name = name.substring( name.lastIndexOf('/') + 1);
-        name = WebConsoleUtil.urlDecode( name );
-        return name;
-    }
-    /**
-     * @see org.apache.felix.webconsole.AbstractWebConsolePlugin#doGet(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
-     */
-    protected final void doGet( HttpServletRequest request, HttpServletResponse response ) throws ServletException,
-        IOException
-    {
-        if ( request.getPathInfo().endsWith( ".txt" ) )
-        {
-            response.setContentType( "text/plain; charset=utf-8" );
-            ConfigurationWriter pw = new PlainTextConfigurationWriter( response.getWriter() );
-            printConfigurationStatus( pw, ConfigurationPrinter.MODE_TXT, getRequestedPrinterName(request) );
-            pw.flush();
-        }
-        else if ( request.getPathInfo().endsWith( ".zip" ) )
-        {
-            String type = getServletContext().getMimeType( request.getPathInfo() );
-            if ( type == null )
-            {
-                type = "application/x-zip";
-            }
-            response.setContentType( type );
-
-            ZipOutputStream zip = new ZipOutputStream( response.getOutputStream() );
-            zip.setLevel( Deflater.BEST_SPEED );
-            zip.setMethod( ZipOutputStream.DEFLATED );
-
-            final ConfigurationWriter pw = new ZipConfigurationWriter( zip );
-            printConfigurationStatus( pw, ConfigurationPrinter.MODE_ZIP, getRequestedPrinterName(request) );
-            pw.flush();
-
-            addAttachments( pw, ConfigurationPrinter.MODE_ZIP );
-            zip.finish();
-        }
-        else if ( request.getPathInfo().endsWith( ".nfo" ) )
-        {
-            WebConsoleUtil.setNoCache( response );
-            response.setContentType( "text/html; charset=utf-8" );
-
-            final String name = getRequestedPrinterName(request);
-
-            HtmlConfigurationWriter pw = new HtmlConfigurationWriter( response.getWriter() );
-            pw.println ( "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"" );
-            pw.println ( "  \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">" );
-            pw.println ( "<html xmlns=\"http://www.w3.org/1999/xhtml\">" );
-            pw.println ( "<head><title>dummy</title></head><body><div>" );
-
-            Collection printers = getPrintersForLabel(name);
-            if ( printers != null )
-            {
-                for (Iterator i = printers.iterator(); i.hasNext();)
-                {
-                    final ConfigurationPrinterAdapter desc = (ConfigurationPrinterAdapter) i.next();
-                    pw.enableFilter( desc.escapeHtml() );
-                    printConfigurationPrinter( pw, desc, ConfigurationPrinter.MODE_WEB );
-                    pw.enableFilter( false );
-                    pw.println( "</div></body></html>" );
-                    return;
-                }
-            }
-
-            response.sendError( HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Invalid configuration printer: " + name);
-        }
-        else
-        {
-            super.doGet( request, response );
-        }
-    }
-
-
-    /**
-     * @see org.apache.felix.webconsole.AbstractWebConsolePlugin#renderContent(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
-     */
-    protected final void renderContent( HttpServletRequest request, HttpServletResponse response ) throws IOException
-    {
-
-        //ConfigurationWriter pw = new HtmlConfigurationWriter( response.getWriter() );
-        PrintWriter pw = response.getWriter();
-        pw.println( "<script type='text/javascript' src='${appRoot}/res/ui/ui.tabs.paging.js'></script>" );
-        pw.println( "<script type='text/javascript' src='${appRoot}/res/ui/configurationrender.js'></script>" );
-
-        pw.println( "<br/><p class=\"statline\">");
-
-        final Date currentTime = new Date();
-        synchronized ( DISPLAY_DATE_FORMAT )
-        {
-            pw.print("Date: ");
-            pw.println(DISPLAY_DATE_FORMAT.format(currentTime));
-        }
-
-        pw.print("<button type=\"button\" class=\"downloadZip\" style=\"float: right; margin-right: 30px; margin-top: 5px;\">Download Zip</button>");
-        pw.print("<button type=\"button\" class=\"downloadTxt\" style=\"float: right; margin-right: 30px; margin-top: 5px;\">Download Text</button>");
-
-        pw.println("<br/>&nbsp;</p>"); // status line
-
-        // display some information while the data is loading
-        // load the data (hidden to begin with)
-        pw.println("<div id='tabs'> <!-- tabs container -->");
-        pw.println("<ul> <!-- tabs on top -->");
-
-        // print headers only
-        final String pluginRoot = request.getAttribute( WebConsoleConstants.ATTR_PLUGIN_ROOT ) + "/";
-        Collection printers = getConfigurationPrinters();
-        for (Iterator i = printers.iterator(); i.hasNext();)
-        {
-            final ConfigurationPrinterAdapter desc = (ConfigurationPrinterAdapter) i.next();
-            if ( desc.match( ConfigurationPrinter.MODE_WEB ) )
-            {
-                final String label = desc.label;
-                final String title = desc.title;
-                pw.print("<li><a href='" + pluginRoot + URLEncoder.encode(label) + ".nfo'>" + title + "</a></li>" );
-            }
-        }
-        pw.println("</ul> <!-- end tabs on top -->");
-        pw.println();
-
-        pw.println("</div> <!-- end tabs container -->");
-
-        pw.println("<div id=\"waitDlg\" title=\"${configStatus.wait}\" class=\"ui-helper-hidden\"><img src=\"${appRoot}/res/imgs/loading.gif\" alt=\"${configStatus.wait}\" />${configStatus.wait.msg}</div>");
-
-        pw.flush();
-    }
-
-    private List getPrintersForLabel(final String label)
-    {
-        List list = null;
-        for ( Iterator cpi = getConfigurationPrinters().iterator(); cpi.hasNext(); )
-        {
-            final ConfigurationPrinterAdapter desc = (ConfigurationPrinterAdapter) cpi.next();
-            if (desc.label.equals( label ) )
-            {
-                if ( list == null )
-                {
-                    list = new ArrayList();
-                    list.add(desc);
-                }
-            }
-        }
-        return list;
-    }
-
-    private void printConfigurationStatus( ConfigurationWriter pw, final String mode, final String optionalLabel )
-    {
-        // check if we have printers for that label
-        Collection printers = getPrintersForLabel(optionalLabel);
-        if ( printers == null )
-        {
-            // if not use all
-            printers = getConfigurationPrinters();
-        }
-
-        for ( Iterator cpi = printers.iterator(); cpi.hasNext(); )
-        {
-            final ConfigurationPrinterAdapter desc = (ConfigurationPrinterAdapter) cpi.next();
-            if ( desc.match(mode) )
-            {
-                printConfigurationPrinter( pw, desc, mode );
-            }
-        }
-    }
-
-    private final synchronized List getConfigurationPrinters()
-    {
-        if ( cfgPrinterTracker == null )
-        {
-            try
-            {
-                cfgPrinterTracker = new ServiceTracker( getBundleContext(),
-                        getBundleContext().createFilter("(|(" + Constants.OBJECTCLASS + "=" + ConfigurationPrinter.class.getName() + ")" +
-                                "(&(" + WebConsoleConstants.PLUGIN_LABEL + "=*)(&("
-                                + WebConsoleConstants.PLUGIN_TITLE + "=*)("
-                                + WebConsoleConstants.CONFIG_PRINTER_MODES + "=*))))"),
-                        null );
-            }
-            catch (InvalidSyntaxException e)
-            {
-                // ignore
-            }
-            cfgPrinterTracker.open();
-            cfgPrinterTrackerCount = -1;
-        }
-
-        if ( cfgPrinterTrackerCount != cfgPrinterTracker.getTrackingCount() )
-        {
-            SortedMap cp = new TreeMap();
-            ServiceReference[] refs = cfgPrinterTracker.getServiceReferences();
-            if ( refs != null )
-            {
-                for ( int i = 0; i < refs.length; i++ )
-                {
-                    final ServiceReference ref = refs[i];
-                    final Object service = cfgPrinterTracker.getService( ref );
-                    if ( service != null )
-                    {
-                        final ConfigurationPrinterAdapter desc = ConfigurationPrinterAdapter.createAdapter(service, ref);
-                        if ( desc != null )
-                        {
-                            addConfigurationPrinter( cp, desc, ref.getBundle() );
-                        }
-                    }
-                }
-            }
-            configurationPrinters = new ArrayList(cp.values());
-            cfgPrinterTrackerCount = cfgPrinterTracker.getTrackingCount();
-        }
-
-        return configurationPrinters;
-    }
-
-
-    private final void addConfigurationPrinter( final SortedMap printers,
-            final ConfigurationPrinterAdapter desc,
-            final Bundle provider)
-    {
-        desc.title = getTitle(desc.title, provider );
-        String sortKey = desc.title;
-        if ( printers.containsKey( sortKey ) )
-        {
-            int idx = -1;
-            String idxTitle;
-            do
-            {
-                idx++;
-                idxTitle = sortKey + idx;
-            }
-            while ( printers.containsKey( idxTitle ) );
-            sortKey = idxTitle;
-        }
-        if ( desc.label == null )
-        {
-            desc.label = sortKey;
-        }
-        printers.put( sortKey, desc );
-    }
-
-
-    // This is Sling stuff, we comment it out for now
-    //    private void printRawFrameworkProperties(PrintWriter pw) {
-    //        pw.println("*** Raw Framework properties:");
-    //
-    //        File file = new File(getBundleContext().getProperty("sling.home"),
-    //            "sling.properties");
-    //        if (file.exists()) {
-    //            Properties props = new Properties();
-    //            InputStream ins = null;
-    //            try {
-    //                ins = new FileInputStream(file);
-    //                props.load(ins);
-    //            } catch (IOException ioe) {
-    //                // handle or ignore
-    //            } finally {
-    //                IOUtils.closeQuietly(ins);
-    //            }
-    //
-    //            SortedSet keys = new TreeSet(props.keySet());
-    //            for (Iterator ki = keys.iterator(); ki.hasNext();) {
-    //                Object key = ki.next();
-    //                infoLine(pw, null, (String) key, props.get(key));
-    //            }
-    //
-    //        } else {
-    //            pw.println("  No Framework properties in " + file);
-    //        }
-    //
-    //        pw.println();
-    //    }
-
-
-    private final void printConfigurationPrinter( final ConfigurationWriter pw,
-            final ConfigurationPrinterAdapter desc,
-            final String mode )
-    {
-        pw.title( desc.title );
-        try
-        {
-            desc.printConfiguration(pw, mode);
-        }
-        catch ( Throwable t )
-        {
-            pw.println();
-            pw.println( "Configuration Printer failed: " + t.toString() );
-            pw.println();
-            log( "Configuration Printer " + desc + " failed", t );
-        }
-        pw.end();
-    }
-
-
     /**
      * Renders an info line - element in the framework configuration. The info line will
      * look like:
@@ -428,270 +56,4 @@
 
         pw.println();
     }
-
-    private final String getTitle( final String title, final Bundle provider )
-    {
-        if ( !title.startsWith( "%" ) )
-        {
-            return title;
-        }
-
-        ResourceBundle res = resourceBundleManager.getResourceBundle( provider, DEFAULT );
-        return res.getString( title.substring( 1 ) );
-    }
-
-    private abstract static class ConfigurationWriter extends PrintWriter
-    {
-
-        ConfigurationWriter( Writer delegatee )
-        {
-            super( delegatee );
-        }
-
-
-        abstract void title( String title );
-
-
-        abstract void end();
-
-
-        public void handleAttachments( final String title, final URL[] urls ) throws IOException
-        {
-            throw new UnsupportedOperationException( "handleAttachments not supported by this configuration writer: "
-                + this );
-        }
-
-    }
-
-    private static class HtmlConfigurationWriter extends ConfigurationWriter
-    {
-
-        // whether or not to filter "<" signs in the output
-        private boolean doFilter;
-
-
-        HtmlConfigurationWriter( Writer delegatee )
-        {
-            super( delegatee );
-        }
-
-
-        void enableFilter( final boolean doFilter )
-        {
-            this.doFilter = doFilter;
-        }
-
-
-        public void title( String title )
-        {
-        }
-
-
-        public void end()
-        {
-        }
-
-
-        // IE has an issue with white-space:pre in our case so, we write
-        // <br/> instead of [CR]LF to get the line break. This also works
-        // in other browsers.
-        public void println()
-        {
-            if ( doFilter )
-            {
-                this.write('\n'); // write <br/>
-            }
-            else
-            {
-                super.println();
-            }
-        }
-
-        // some VM implementation directly write in underlying stream, instead of
-        // delegation to the write() method. So we need to override this, to make
-        // sure, that everything is escaped correctly
-        public void print(String str)
-        {
-            final char[] chars = str.toCharArray();
-            write(chars, 0, chars.length);
-        }
-
-
-        private final char[] oneChar = new char[1];
-
-        // always delegate to write(char[], int, int) otherwise in some VM
-        // it cause endless cycle and StackOverflowError
-        public void write(final int character)
-        {
-            synchronized (oneChar)
-            {
-                oneChar[0] = (char) character;
-                write(oneChar, 0, 1);
-            }
-        }
-
-        // write the characters unmodified unless filtering is enabled in
-        // which case the writeFiltered(String) method is called for filtering
-        public void write(char[] chars, int off, int len)
-        {
-            if (doFilter)
-            {
-                chars = WebConsoleUtil.escapeHtml(new String(chars, off, len)).toCharArray();
-                off = 0;
-                len = chars.length;
-            }
-            super.write(chars, off, len);
-        }
-
-
-        // write the string unmodified unless filtering is enabled in
-        // which case the writeFiltered(String) method is called for filtering
-        public void write( final String string, final int off, final int len )
-        {
-            write(string.toCharArray(), off, len);
-        }
-
-    }
-
-    private void addAttachments( final ConfigurationWriter cf, final String mode )
-    throws IOException
-    {
-        for ( Iterator cpi = getConfigurationPrinters().iterator(); cpi.hasNext(); )
-        {
-            // check if printer supports zip mode
-            final ConfigurationPrinterAdapter desc = (ConfigurationPrinterAdapter) cpi.next();
-            if ( desc.match(mode) )
-            {
-                final URL[] attachments = desc.getAttachments(mode);
-                if ( attachments != null )
-                {
-                    cf.handleAttachments( desc.title, attachments );
-                }
-            }
-        }
-
-    }
-
-    private static class PlainTextConfigurationWriter extends ConfigurationWriter
-    {
-
-        PlainTextConfigurationWriter( Writer delegatee )
-        {
-            super( delegatee );
-        }
-
-
-        public void title( String title )
-        {
-            print( "*** " );
-            print( title );
-            println( ":" );
-        }
-
-
-        public void end()
-        {
-            println();
-        }
-    }
-
-    private static class ZipConfigurationWriter extends ConfigurationWriter
-    {
-        private final ZipOutputStream zip;
-
-        private int counter;
-
-
-        ZipConfigurationWriter( ZipOutputStream zip )
-        {
-            super( new OutputStreamWriter( zip ) );
-            this.zip = zip;
-        }
-
-
-        public void title( String title )
-        {
-            String name = MessageFormat.format( "{0,number,000}-{1}.txt", new Object[]
-                { new Integer( counter ), title } );
-
-            counter++;
-
-            ZipEntry entry = new ZipEntry( name );
-            try
-            {
-                zip.putNextEntry( entry );
-            }
-            catch ( IOException ioe )
-            {
-                // should handle
-            }
-        }
-
-        private OutputStream startFile( String title, String name)
-        {
-            final String path = MessageFormat.format( "{0,number,000}-{1}/{2}", new Object[]
-                 { new Integer( counter ), title, name } );
-            ZipEntry entry = new ZipEntry( path );
-            try
-            {
-                zip.putNextEntry( entry );
-            }
-            catch ( IOException ioe )
-            {
-                // should handle
-            }
-            return zip;
-        }
-
-        public void handleAttachments( final String title, final URL[] attachments)
-        throws IOException
-        {
-            for(int i = 0; i < attachments.length; i++)
-            {
-                final URL current = attachments[i];
-                final String path = current.getPath();
-                final String name;
-                if ( path == null || path.length() == 0 )
-                {
-                    // sanity code, we should have a path, but if not let's
-                    // just create some random name
-                    name = "file" + Double.doubleToLongBits( Math.random() );
-                }
-                else
-                {
-                    final int pos = path.lastIndexOf('/');
-                    name = (pos == -1 ? path : path.substring(pos + 1));
-                }
-                final OutputStream os = this.startFile(title, name);
-                final InputStream is = current.openStream();
-                try
-                {
-                    IOUtils.copy(is, os);
-                }
-                finally
-                {
-                    IOUtils.closeQuietly(is);
-                }
-                this.end();
-            }
-
-            // increase the filename counter
-            counter++;
-        }
-
-
-        public void end()
-        {
-            flush();
-
-            try
-            {
-                zip.closeEntry();
-            }
-            catch ( IOException ioe )
-            {
-                // should handle
-            }
-        }
-    }
 }
